首先给出正确代码
法一,将数字各项进行比对
#include<stdio.h>
int main()
{
long long int i,m,n;
printf("0");
for(i=1;i<200000;i++){
n=i*i;
m=i;
while(m>0){
if(m%10!=n%10) break;
m/=10;
n/=10;
if(m==0) printf(" %d",i);
}
}
return 0;
}
法二:将数字整体进行比对(取余运算的灵活运用)
#include<stdio.h>
int main()
{
long long int i,m,n;
printf("0");
for(i=1;i<200000;i++){
n=i*i;
//确定取余的位数
for(m=10;;m*=10){
if(i<m) break;
}
//判断i是否为自守数
if(i==(n%m)) printf(" %lld",i);
}
return 0;
}
明显,第二种方法的代码更简洁,但是不好想,因为大家对比数字一般都是先把各位数取出来,然后再求和对比或者各位数字逐一对比。
不知道大家发现没,在这里的三个变量均定义为了long long int型,为什么要这么做呢?
仔细观察,n=i*i,如果i已经是个五位数,如果n是int型,那么很有可能n会溢出;
那我的i还是可以为int型呀,毕竟是200000以内。
但是i*i的结果还是会保存为int型,把这个int型的值赋给n,就算n是个long long int,也还是会精度不够。
所以,这里统一把i、m、n令为long long int,这样可以避免算术运算导致的精度缺失。
当然,还有一种做法,就是在n=i*i时进行强制类型转换,变成n=(long long int)i*i,这样也不会造成精度缺失。
当前几项能正确打印,后几项高位数字无法打印,那就要考虑是不是变量定义范围过小的问题了。
solved