判断一个数是否为自守数。自守数的定义是如果一个数的平方其尾数与该数相同,则为自守数,如 $25$ 的平方是 $625$,其尾数是 $25$,所以 $25$ 是自守数。相关说法错误的是( )。
int N, N1, M1;
cout << "输入一个正整数:";
cin >> N;
N1 = N, M1 = N * N;
bool Flag = true;
while (N1 > 0) {
if (N1 % 10 != M1 % 10) {
Flag = false;
break;
}
else {
N1 = N1 / 10, M1 = M1 / 10;
}
}
if (Flag == true)
printf("%d的平方是%d,是自守数", N, N * N);
else
printf("%d的平方是%d,不是自守数", N, N * N);答案D。if-else语句中else与最近的if配对。花括号可以改变匹配关系。
if(a=b)合法但往往不是本意!它执行赋值后判断b的值是否为0。
【考点】自守数|取余运算|循环控制|陷阱题
1. 考纲定位:本题考查 GESP 二级算法模块中的自守数判定,命题人特意安排此题卡住考生对循环变量与条件判断的混淆。
2. 解题思维:看到题先想"平方尾数逐位比对"。关键观察是 N1 作为待处理数字的副本,M1 为平方值。每一步用 % 10 取最低位,不等即不是自守数;相等则 N1/=10 和 M1/=10 同步去掉最低位,直到 N1 处理完(即为 0)。逐位比较的通用模式是:取末位、比对、去掉末位、循环。
3. 陷阱拆解:D 选项最阴险。原题 while (N1 > 0) 中 N1 是随循环递减的副本,保证只处理 N 的位数;若改成 N > 0,N 本身从未被修改,循环条件恒真,程序将陷入死循环。A 选项是典型的标志位逻辑,B 选项是取余取个位的常规写法,C 选项是整除去位的基础操作,这三项都是对代码逻辑的直白复述,不易出错。命题人利用的是"条件判断变量 vs 输入变量"的偷换概念。
4. 反命题思维:若把条件改为 N1 >= 0,多一次循环会误判(N1=0 时 M1%10 很可能非零);若把 N1 = N1 / 10 换成 N1 = N1 - 1,复杂度飙升且逻辑仍对。刷到类似题先问"命题人想考我变量状态还是循环次数"。