题目描述
自守数” 是平方尾数等于该数自身的自然数。例如:
25*25=625 76*76=5776 9376*9376=87909376
输入:n(自守数的位数)(n <= 15)
输出:n 位的自守数
思路
我们知道如果x为自守数,则x%10也为自守数,那么,其中表示n位的自守数。我们可以依次求出1,2,3……n-1位自守数,最后对k和遍历得到的可能取值,再进行判断。
(当n比较大时,如果直接利用来判断是否为自守数会溢出。
我们可以通过
又,即两者互素,不含相同素因子
或来判断是否为自守数)
注:表示a,b除以c的余数相同
代码实现
#include <stdio.h>
long long int intPow(int a,int n){
long long int num=1;
for(int i=0;i<n;i++){
num*=a;
}
return num;
}
int num(int n,long long int nums[15][10]){
int count=0;//n位自守数的个数
if(n==1) {
return 3;
}
num(n-1,nums);
for(int k=1;k<10;k++) {
for(int i=0;i<n-1;i++){
for(int j=0;j<10;j++){
if(nums[i][j]==0){
break;
}
//判断是否为自守数
if((k*intPow(10,n-1)+nums[i][j])%intPow(2,n)==0 && (k*intPow(10,n-1)+nums[i][j])%intPow(5,n)==1){
nums[n-1][count]=k*intPow(10,n-1)+nums[i][j];
count++;
}else if((k*intPow(10,n-1)+nums[i][j])%intPow(5,n)==0 && (k*intPow(10,n-1)+nums[i][j])%intPow(2,n)==1){
nums[n-1][count]=k*intPow(10,n-1)+nums[i][j];
count++;
}
}
}
}
return count;
}
int main(){
long long int n,nums[15][10]={1,5,6,}; //nums[i][j]表示i+1位的第j+1个自守数
//同时初始化位数为一的自守数;
scanf("%lld",&n);
int count=num(n,nums);
for(int i=0;i<count;i++){
printf("%lld\n",nums[n-1][i]);
}
return 0;
}