快速找到不愉快的号码

时间:2015-10-24 22:53:22

标签: c++ math numbers combinations number-theory

我正在尝试解决一个问题。给定一系列整数,用户必须找到给定范围内不满意的数量。

Unhappy number - 一个数字n,这样迭代这个从n开始的平方数字平方映射永远不会达到数字1.

我尝试过使用蛮力方法计算数字的平方和,如果在任何时刻它都等于其中任何一个(4,16,37,58,89,145,42,20)那是一个不愉快的数字。

这种方法给TLE有什么更好的方法吗?

范围在1到10 ^ 18之间。

2 个答案:

答案 0 :(得分:4)

您的范围在1到10之间 18 。这意味着您的号码最多包含18位数字。

考虑到一个数字的最大平方为9 2 = 81,在最大数字为18 * 81 = 1458后进行平方数字和。

因此,一个平方数字加上一个约1500个元素的查找表就足够了。

或两个平方数字加上一个~330个元素的查找表:

static const bool unhappy[330] {
    1,0,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,
    1,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,
    1,1,1,0,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,
    0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,
    1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,0,0,1,
    1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,0,1,1,1,1,1,0,1,1,0
}

inline bool is_unhappy(uint64_t n) {
    while (n >= 330) {
        int r = 0;
        while (n > 0) {
            int d = n % 10;
            r += d*d;
            n /= 10;
        }
        n = r;
    }

    return unhappy[n];
}

答案 1 :(得分:0)

#include <map>
#include <set>

bool happy(int number) {
    static std::map<int, bool> cache;

    std::set<int> cycle;
    while (number != 1 && !cycle.count(number)) {
        if (cache.count(number)) {
            number = cache[number] ? 1 : 0;
            break;
        }
        cycle.insert(number);
        int newnumber = 0;
        while (number > 0) {
            int digit = number % 10;
            newnumber += digit * digit;
            number /= 10;
        }
        number = newnumber;
    }
    bool happiness = number == 1;
    for (std::set<int>::const_iterator it = cycle.begin();
    it != cycle.end(); it++)
    cache[*it] = happiness;
    return happiness;
}

#include <iostream>

int main() {
    for (int i = 1; i < 10; i++)
      if (!happy(i))
        std::cout << i << std::endl;
    return 0;
}

输出:

2
3
4
5
6
8
9

逻辑和大部分代码来自此处:https://tfetimes.com/c-happy-numbers/