从键盘输入一个自然数K(K>1),若存在自然数M和N(M>N),使得K^M和K^N均大于或等于1000,且它们的末尾三位数相等,则称M和N是一对“K尾相等数”。请编一个程序,输出M+N值最小的K尾相等数。
测试数据:
Sample input |
Output for the input |
2 25 1000 1234 111111 1000003 123454321 |
120 6 3 56 52 102 27
|
解:
对于一个数,它的幂是无穷多个的,但是末尾三位数只有1000种。这表明当第一次重复出现大于等于1000的末尾三位数时,这就是我们要求的M和N了
源代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define LEN 1000
void main(){
int k,i,tail[LEN],m,flag;
while(1){
scanf("%d",&k); //输入K
if(k==1) exit(0); //如果K等于1则退出
flag=0; //初始化
i=m=1; //m为当前幂的次数,i等于k的m次幂
memset(tail,0,sizeof(int)*LEN);
/* 当K大于1000时我们只要对它的末尾三位数进行幂运算,
* 这样不影响结果,但减少了幂运算后值的大小
*/
if(k>=LEN) {
k=k%LEN;
flag=1;
}
while(1){
i*=k;
if(i>=LEN || flag==1){
if(tail[i%LEN]==0) tail[i%LEN]=m; //这个末尾三位数是第一次出现
else {tail[i%LEN]+=m;break;} //末尾三位数出现了第二次,退出循环
flag=1;
}
if(i>=LEN) i=i%LEN;
m++;
}
printf("%d ",tail[i%LEN]);
}
}
#include<string.h>
#include<stdlib.h>
#define LEN 1000
void main(){
int k,i,tail[LEN],m,flag;
while(1){
scanf("%d",&k); //输入K
if(k==1) exit(0); //如果K等于1则退出
flag=0; //初始化
i=m=1; //m为当前幂的次数,i等于k的m次幂
memset(tail,0,sizeof(int)*LEN);
/* 当K大于1000时我们只要对它的末尾三位数进行幂运算,
* 这样不影响结果,但减少了幂运算后值的大小
*/
if(k>=LEN) {
k=k%LEN;
flag=1;
}
while(1){
i*=k;
if(i>=LEN || flag==1){
if(tail[i%LEN]==0) tail[i%LEN]=m; //这个末尾三位数是第一次出现
else {tail[i%LEN]+=m;break;} //末尾三位数出现了第二次,退出循环
flag=1;
}
if(i>=LEN) i=i%LEN;
m++;
}
printf("%d ",tail[i%LEN]);
}
}