题解 P7840 【「PMOI-4」人赢】

· · 题解

对于这一题对于 100\% 的数据 1 \le k \le 10^{12} 则显然不会是暴力打解了,一定是有规律的,因此可以从这方面去考虑。

Subtask 1

显然 1 \le k \le 10^6 只需要暴力枚举即可,复杂度 \mathcal{O}(n),注意在计算 a_i=a_{i-1} \times a_{i-2} \bmod 10 的时候如果单纯按原式代入计算 a_i 的话那么在后面可能会爆 \texttt{int},所以注意:

因为只计算个位数,只用算出 a_{i-1} \bmod 10, a_{i-2} \bmod 10 (也就是个位数即可),应该把式子变成:

a_i=(a_{i-1}\bmod 10) \times (a_{i-2}\bmod 10) \bmod 10

直接打暴力即可:(30 pts

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,m,k;
    cin>>n>>m>>k;
    int a[100005];
    a[1]=n,a[2]=m;
    for(int i=3;i<=k;i++)
        a[i]=(a[i-1]%10*a[i-2]%10)%10;//按照式子计算得出答案
    cout<<a[k];//最后输出即可
    return 0;
}

Subtask 2

显然不能打暴力了,对于 1 \le k \le 10^{12} 需要找规律,因此我们尝试枚举部分情况的结果:

下表中 k 均为 15

(n,m) a_1 a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9 a_{10} a_{11} a_{12} a_{13} a_{14} a_{15}
(4,9) 4 9 6 4 4 6 4 4 6 4 4 6 4 4 6
(7,8) 7 8 6 8 8 4 2 8 6 8 8 4 2 8 6
(3,9) 3 9 7 3 1 3 3 9 7 3 1 3 3 9 7
(6,8) 6 8 8 4 2 8 6 8 8 4 2 8 6 8 8
(7,3) 7 3 1 3 3 9 7 3 1 3 3 9 7 3 1

上图中就是几个数对按照题目要求得出的 a_1 \sim a_{15} 数。

在图中:

(n,m) a_1 a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9 a_{10} a_{11} a_{12} a_{13} a_{14} a_{15}
(4,9) 4 9 \color{red}6 \color{red}4 \color{red}4 \color{red}6 \color{red}4 \color{red}4 \color{purple}6 \color{purple}4 \color{purple}4 \color{purple}6 \color{purple}4 \color{purple}4 6
(7,8) 7 8 \color{red}6 \color{red}8 \color{red}8 \color{red}4 \color{red}2 \color{red}8 \color{purple}6 \color{purple}8 \color{purple}8 \color{purple}4 \color{purple}2 \color{purple}8 6
(3,9) 3 9 \color{red}7 \color{red}3 \color{red}1 \color{red}3 \color{red}3 \color{red}9 \color{purple}7 \color{purple}3 \color{purple}1 \color{purple}3 \color{purple}3 \color{purple}9 7
(6,8) 6 8 \color{red}8 \color{red}4 \color{red}2 \color{red}8 \color{red}6 \color{red}8 \color{purple}8 \color{purple}4 \color{purple}2 \color{purple}8 \color{purple}6 \color{purple}8 8
(7,3) 7 3 \color{red}1 \color{red}3 \color{red}3 \color{red}9 \color{red}7 \color{red}3 \color{purple}1 \color{purple}3 \color{purple}3 \color{purple}9 \color{purple}7 \color{purple}3 1

我们可以发现\color{red}红色部分和\color{purple}紫色部分的数字是完全相同的,不妨猜测所有数列都以 6 次为循环。

根据这个思路我们用 k 来看看,因为 a_1,a_2 不考虑在数列以内,因此对于 k 在循环中的点的公式为 ans=(k-3) \bmod 6 +3 ,因此代入计算即可。

#include<bits/stdc++.h>
using namespace std;
int main(){
    long long n,m,k;
    cin>>n>>m>>k;
    int a[10],b[7];
    a[1]=n,a[2]=m;//a1,a2按照前面算出来,因为数列中不包含
    for(int i=3;i<=9;i++)//循环
        a[i]=(a[i-1]%10*a[i-2]%10)%10;//按照前面算出第一个数列也就是六次循环算出的结果
    cout<<a[(k-3)%6+3];//代入公式计算算出即可
    return 0;
}

令:如果遇到相乘 a_2,a_31,5,6,只需输出 1,5,6 即可;如果遇到 a_i=0 输出 0 即可。

综上,求解方法为:

a_i=(a_{i-1}\bmod 10) \times (a_{i-2}\bmod 10) \bmod 10

令:

g(x)=\min_{1 \le i \le x,a_i \in [1,9]} a r(x)=\max_{1 \le i \le x,a_i \in [1,9]} a

则:

\Longrightarrow ans = \begin{cases}g(x)\in\{0\}&ans=0\\r(2),r(3) \in \{5\}&ans=5\\r(2),r(3) \in \{6\}&ans=6\\else&ans=a_{(k-3) \bmod 6 +3}\end{cases}

亲测,稳过