K尾相等数
时间限制:3000 ms | 内存限制:65535 KB
描述
输入一个自然数K(K>1),如果存在自然数M和N(M>N),使得K^M和K^N均大于等于1000,且他们的末尾三位数相等,则称M和N是一对“K尾相等数”。下面请编程求出M+N最小的K尾相等数
。
输入
第一行包含一个正整数T,T<10000,表示有T组数据;
随后有N行,每行包括一个整数K(K<2*10^10);
输出
对于输入的每个整数K,输出对应的M+N的最小值;
样例输入
1 2
样例输出
120
比较简单的一道数论题。对于一个数,它的幂是无穷无尽的但是我们可以注意到末尾三位数只有1000个,所以我们可以考虑开一个大小1000的数组记录末尾为i的数第一次出现的幂的大小。然后在后面的循环中判断这个三位数是否出现即可。即求n^i%1000,可以看成二分快速幂
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define LL long long
using namespace std;
LL Time[1005],t,n;
LL divm(LL a,LL b,LL c){
LL t=1,y=a;
while(b>0){
if(b&1)t=(t*y)%c;
y=(y*y)%c;
b>>=1;
}
return t;
}
int main(){
cin>>t;
while(t--){
cin>>n;
memset(Time,0,sizeof(Time));
LL m=n;
LL cnt=1;
while(n<1000){
n*=m;
cnt++;
}
for(LL i=cnt;;i++){
LL temp=divm(m,i,1000);
if(Time[temp]!=0){
cout<<Time[temp]+i<<endl;
break;
}
Time[temp]=i;
}
}
}
虽然取模得到的数一定是Int范围内,但是k给的比较大,二分快速幂中有可能溢出,保守起见使用longlong