问题描述:
![](https://i-blog.csdnimg.cn/blog_migrate/0619c8ff665d6082f06ba45ee0a11667.png)
样例说明与规模限制:
![](https://i-blog.csdnimg.cn/blog_migrate/5b4913cfc4419fda01e60cd854a01c6f.png)
思路解析:
1.预处理:
(1)把0-9的几次方列一遍,很容易发现:对0-9的次方分别取模10后,都会出现循环。要使循环出现所需的次数却不同;
(2)将0-9每位的循环所需次数列入一个数组a;
2.读入数据:
用字符串形式读入p,并从高位向低位,将每一位转化为int类型,并不断取模(保证res不越界)。以确定该次方对应的循环前的位数res;
3.处理特殊情况:
(1)n恰好是模数10的倍数,取模后一定为0;
(2) res对应的位数恰好是循环所需次数,应该把0改为循环所需次数 (4%4=0,此时res=0,而实际上我们需要把res算做4)
4.输出:
求对n取res次方的个位数字(相当于取模10),并输出;
5.进行下一组测试样例的判断:
代码讲解:
#include<bits/stdc++.h>
using namespace std;
//0: 0,0 1次一循环
//1: 1,1 1次一循环
//2: 2,4,8,6,2 4次一循环
//3: 3,9,7,1,3 4次一循环
//4: 4,6,4 2次一循环
// ....
//把0-9的循环次数输入a[0]-a[9]
int a[]={1,1,4,4,2,1,1,4,4,2};
void fun()
{
int n;
string s;
cin>>n>>s;
//判断循环所需次数
n=n%10;
int m=a[n];
int res=0;
//将输入的字符串转化为res这个int类型的数,并不断将res按照循环所需次数取模(以保证数据不会越界)
//使得res表示为循环前的第几位
//因为循环100次与循环k*100次是等价的,所以我们只用取p的最后两位就可以了(引用自评论区,id:翔天呀)
for(int i=(int)(s.length())-2;i<=(int)(s.length()-1);i++)
{
res=(res*10+s[i]-'0')%m;
}
//因为p>1,如果原来的n是10的倍数(现在n==0),结果对10取模后一定为零
if(n==0)
{
cout<<0<<"\n";
return;
}
//如果结果不断取模后,%循环次数=0,证明循环到最后一位(最大位)
//e.g.如果循环次数为四位,4%4==0,证明结果是第四位
if(res==0) res=a[n];
//此时的res为所对应的循环前的第几位,所以对n取res次方,即为所求值
cout<<(int)(pow(n,res))%10<<"\n";
return;
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t=0;
//输入测试样例数
cin>>t;
//进行每次的测试
while(t--) fun();
return 0;
}