UVALive6222 Unhappy Numbers【数学】(RE)

Numbers have feelings too! For any positive integer, take the sum of the squares of each of its digits, and add them together. Take the result, and do it again. A number is Happy if, after repeating this process a finite number of times, the sum is 1. Some happy numbers take more iterations of this process to get to 1 than others, and that would be referred to as its distance from happiness. 1’s distance from happiness is 0. 23’s distance from happiness is 3, since 2^2 + 3^2 = 13, 1^2 + 3^2 = 10, and 1^2 + 0^2 = 1. Numbers are Unhappy if they are infinitely far away from happiness because they get stuck in a loop.

Given the lower end and upper end of a range of integers, determine how many Unhappy numbers are in that range (inclusive).

Input

There will be several test cases in the input. Each test case will consist of two positive integers, lo and hi (0 < lo ≤ hi ≤ 1018) on a single line, with a single space between them. Input will terminate with two ‘0’s.

Output

For each test case, output a single integer on its own line, indicating the count of Unhappy Numbers between lo and hi (inclusive). Output no extra spaces, and do not separate answers with blank lines.

Sample Input

1 10

1 100

0 0

Sample Output

7

80


Regionals 2012 >> North America - Southeast USA


问题链接UVALive6222 Unhappy Numbers

问题简述:(略)

问题分析

  某一个正整数n,对其各位数字分别平方再求和得到一个新数,重复同样的计算,最终和变成1,则称n为快乐数;如果出现循环变不成1则不是快乐数。

程序说明

  使用set来判重复是一个好做法。

  函数ishn()用来判定一个数是否是快乐数。


题记:(略)


参考链接UVA944 Happy Numbers【数学】


RE的C++语言程序如下:

/* UVALive6222 Unhappy Numbers */

#include <bits/stdc++.h>

using namespace std;

const int N = 9 * 9 * 18;
const int N2 = 1e6;
int hn[N + 1];
int prefixsum[N2 + 1];

int ishn(int n) {
    set<int> s;
    while (n != 1) {
        int sum = 0;
        while (n) {
            int d = n % 10;
            sum += d * d;
            n /= 10;
        }
        n = sum;
        if (s.count(n))
            break;
        else
            s.insert(n);
    }
    return n == 1;
}

int isHN(unsigned long long n)
{
    if(n > N) {
        int sum = 0;
        while (n) {
            int d = n % 10;
            sum += d * d;
            n /= 10;
        }
        return hn[sum];
    } else
        return hn[n];
}

void maketable()
{
    for(int i = 1; i <= N; i++)
        hn[i] = ishn(i);

    prefixsum[0] = 0;
    for(int i = 1; i <= N2; i++)
        if(isHN(i))
            prefixsum[i] = prefixsum[i - 1];
        else
            prefixsum[i] = prefixsum[i - 1] + 1;
}

int main()
{
    unsigned long long lo, hi;

    maketable();

    while(~scanf("%lld%lld", &lo, &hi) && (lo || hi)) {
        int cnt = 0;
//        for(long long i = lo; i <= hi; i++)
//            if(!isHN(i))
//                cnt++;

        if(hi <= N2) {
            cnt = prefixsum[hi] - prefixsum[lo - 1];
        } else if(lo < N2) {
            cnt = prefixsum[N2] - prefixsum[lo - 1];
            for(unsigned long long i = N2 + 1; i <= hi; i++)
                if(!isHN(i))
                    cnt++;
        } else {
            for(unsigned long long i = lo + 1; i <= hi; i++)
                if(!isHN(i))
                    cnt++;
        }

        printf("%d\n", cnt);
    }

    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值