题解 | #自守数#

自守数

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 == 10i == 100i == 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;
    }
}

全部评论

相关推荐

09-15 12:15
北京大学 Java
geiedaada:倒反天罡,北大爷团子都敢拒!
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务