题解 | #自守数#
自守数
https://www.nowcoder.com/practice/88ddd31618f04514ae3a689e83f3ab8e
解法一:暴力破解
首先来介绍第一种解法,对 [0, n] 区间内的每个数字求平方,然后对n的几位数字进行是否相等判断,若相等则 count++
思路分析:
- 这里就直接给出代码了,外层循环控制的是从1 ~ n,内部求出当前这个数的平方之后再去一一比对即可,此处的主要判断逻辑就在于这个
tmp % 10 != pow_n % 10,通过对每一位去做一个比较,若是发现不相同的话那一定不是自守数 - 最后在当前轮的循环结束后,若
tmp == 0的话则表示所有的位数都比较过了均相同,不是中途break出来的,那么这个数就是【自守数】
代码详解:
int main() {
int n = 0;
int cnt = 0;
cin >> n;
for (int i = 0; i <= n;i++) {
int tmp = i;
int pow_n = pow(i, 2);
while (tmp) {
if(tmp % 10 != pow_n % 10)
break; // 如果遇到不相同的话,直接break
tmp /= 10;
pow_n /= 10;
}
if (tmp == 0) {
cnt++;
}
}
cout << cnt << endl;
}
解法二: 换位取模
思路分析:
- 然后我们再来说说第二种方法此方法我用到了一个
base作为基数,其到一个临界点的时候就会去发生一个变化那这个【临界点】是什么意思呢? [x] 当这个数是在10以内的话,那么它就是一个一位数,所以我们在对平方数取余的时候只需要取出最后面那一位就可以了,即%10[x] 当这个数是在100以内的话,那么它就是一个两位数,所以我们在对平方数取余的时候需要取出最后面的两位,即%100[x] 当这个数是在1000以内的话,那么它就是一个三位数,所以我们在对平方数取余的时候需要取出最后面的三位,即%1000 - 那经过上面这样一分析,你大概也能猜到这个基数
base该如何变化了吧,也就是当这个i == 10、i == 100、i == 1000...这些临界的时候,就要去更换base了
代码详解:
int main() {
int n = 0;
while (cin >> n) {
long cnt = 0, base = 10;
for (int i = 0; i <= n; ++i) {
int pow_n = pow(i, 2);
int tmp = i;
// 如果i到达位数的临界点的话, 基数base要发生变化
if (i == base) {
base *= 10;
}
if (pow_n % base == i) {
cnt++;
}
}
cout << cnt << endl;
}
}
查看19道真题和解析