L2-029 特立独行的幸福 (25分)

L2-029 特立独行的幸福 (25分)
对一个十进制数的各位数字做一次平方和,称作一次迭代。如果一个十进制数能通过若干次迭代得到 1,就称该数为幸福数。1 是一个幸福数。此外,例如 19 经过 1 次迭代得到 82,2 次迭代后得到 68,3 次迭代后得到 100,最后得到 1。则 19 就是幸福数。显然,在一个幸福数迭代到 1 的过程中经过的数字都是幸福数,它们的幸福是依附于初始数字的。例如 82、68、100 的幸福是依附于 19 的。而一个特立独行的幸福数,是在一个有限的区间内不依附于任何其它数字的;其独立性就是依附于它的的幸福数的个数。如果这个数还是个素数,则其独立性加倍。例如 19 在区间[1, 100] 内就是一个特立独行的幸福数,其独立性为 2×4=8。

另一方面,如果一个大于1的数字经过数次迭代后进入了死循环,那这个数就不幸福。例如 29 迭代得到 85、89、145、42、20、4、16、37、58、89、…… 可见 89 到 58 形成了死循环,所以 29 就不幸福。

本题就要求你编写程序,列出给定区间内的所有特立独行的幸福数和它的独立性。

输入格式:
输入在第一行给出闭区间的两个端点:1<A<B≤10
​4
​​ 。

输出格式:
按递增顺序列出给定闭区间 [A,B] 内的所有特立独行的幸福数和它的独立性。每对数字占一行,数字间以 1 个空格分隔。

如果区间内没有幸福数,则在一行中输出 SAD。

输入样例 1:
10 40
输出样例 1:
19 8
23 6
28 3
31 4
32 3
注意:样例中,10、13 也都是幸福数,但它们分别依附于其他数字(如 23、31 等等),所以不输出。其它数字虽然其实也依附于其它幸福数,但因为那些数字不在给定区间 [10, 40] 内,所以它们在给定区间内是特立独行的幸福数。

输入样例 2:
110 120
输出样例 2:
SAD

//对于每一个给出的数A,对其迭代直至出现幸福数,死循环数、1或出现死循环
//若迭代至1,把从A开始迭代的所有数标记为幸福数,把A设为特立独行的数,并为所有数设置独立性
//若迭代至出现幸福数B,把由A开始迭代至B的所有数标记为幸福数,为它们设置独立性,把A设为特立独行的数,此时,B显然不会是特立独行的数(B依附于A)
//特别地,当A就是B时,不将A设为特立独行的数,因为此时不能判断A是否依附于给定范围内的其它数
//若迭代至出现死循环数C,把由A开始迭代至C的所有数标记为死循环数
//若迭代至出现死循环,如A->D->E->...->D,把A至第二个D的所有数标记为死循环数

#include<stdio.h>
#include<math.h>

bool IsPrime(int x)
{
	for (int i = 2; i <= sqrt(x); i++)
		if (x % i == 0)return false;
	return true;
}

int main()
{
	int N, M;
	scanf("%d %d", &N, &M);
	int dnum[10001];    //独立性
	bool Visit[10001] = { false };  //判断死循环
	bool IsHappy[10001] = { false };
	bool IsIndividual[10001] = { false };   //特立独行的数
	bool IsCircle[10001] = { false };       //死循环数
	int Queue[10001];       //每次迭代中所有待处理的数
	int index = 0;
	int num, tnum, add;
	bool check = false;   //true为死循环,false为幸福数
	for (int i = 0; i < M - N + 1; i++)
	{
		num = N + i;
		check = false;
		while (true) {  //对num进行迭代
			if (num == 1 || IsHappy[num]) { //遇到1或是幸福数
				Queue[index++] = num; Visit[num] = true; break;
			}
			else if (Visit[num] || IsCircle[num]) { Queue[index++] = num; Visit[num] = true; check = true; break; } //遇到死循环数
            
			Queue[index++] = num;
			Visit[num] = true;
            
			tnum = 0;
			while(num){
				add = num % 10;
			    tnum += add * add;
                num/=10;
			} 
			num = tnum;
		}
        for (int j = 0; j < index; j++) Visit[Queue[j]] = false;    //初始化Visit数组
        
		if (IsHappy[Queue[index - 1]])      //处理遇到幸福数的情况
		{
            if(index==1)continue;       //若A就是B,跳过处理
			IsIndividual[Queue[index - 1]] = false;     //B一定不是特立独行的数
			IsIndividual[Queue[0]] = true;      //A暂设为特立独行的数
			//printf("[[[%d]]]-%d\n", Queue[0],Queue[index-1]);
			for (int j = index - 2; j >= 0; j--)    //A至B的所有数设为幸福数,并设置独立性
			{
				dnum[Queue[j]] = dnum[Queue[j + 1]] + 1;
				IsHappy[Queue[j]] = true;
			}
		}
		else if (IsCircle[Queue[index - 1]])        //处理遇到死循环数的情况
		{
			for (int j = index - 2; j >= 0; j--)
			{
				IsCircle[Queue[j]] = true;
			}
		}
		else
		{
			if (!check) {   //迭代至到1,标记A为特立独行的数
				IsIndividual[Queue[0]] = true; //printf("---%d---\n", Queue[0]);
			}
			for (int j = 0; j < index; j++)     
			{
				if (check)IsCircle[Queue[j]] = true;    //处理迭代至遇到死循环的情况
				else {                                  //处理迭代至1的情况
					IsHappy[Queue[j]] = true;
					dnum[Queue[j]] = index - j-1;
				}
			}
		}
		
		index = 0;
	}
	int ans = 0;
	for (int i = 0; i < M-N+1; i++)
		if (IsIndividual[N + i]) {
			ans += 1; printf("%d %d\n", N + i, IsPrime(N + i) ? dnum[N + i] * 2 : dnum[N + i]);
		}
	if (ans == 0)printf("SAD");
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
7-6 特立独行幸福 (25) 对一个十进制的各位数字一次平方和称作一次迭代。如果一个十进制能通过若干次迭代得到 1,就称该幸福。1 是一个幸福。此外,例如 19 经过 1 次迭代得到 82,2 次迭代后得到 68,3 次迭代后得到 100,最后得到 1。则 19 就是幸福。显然,在一个幸福迭代到 1 的过程中经过的数字都是幸福,它们的幸福是依附于初始数字的。例如 82、68、100 的幸福是依附于 19 的。而一个特立独行幸福,是在一个有限的区间内不依附于任何其它数字的;其独立性就是依附于它的的幸福的个。如果这个还是个素,则其独立性加倍。例如 19 在区间[1, 100] 内就是一个特立独行幸福,其独立性为 2×4=8。 另一方面,如果一个大于1的数字经过迭代后进入了死循环,那这个就不幸福。例如 29 迭代得到 85、89、145、42、20、4、16、37、58、89、…… 可见 89 到 58 形成了死循环,所以 29 就不幸福。 本题就要求你编写程序,列出给定区间内的所有特立独行幸福和它的独立性。 输入格式: 输入在第一行给出闭区间的两个端点:1<A<B≤10 ​4 ​​ 。 输出格式: 按递增顺序列出给定闭区间 [A,B] 内的所有特立独行幸福和它的独立性。每对数字占一行,数字间以 1 个空格隔。 如果区间内没有幸福,则在一行中输出 SAD。 输入样例 1: 10 40 输出样例 1: 19 8 23 6 28 3 31 4 32 3 注意:样例中,10、13 也都是幸福,但它们别依附于其他数字(如 23、31 等等),所以不输出。其它数字虽然其实也依附于其它幸福,但因为那些数字不在给定区间 [10, 40] 内,所以它们在给定区间内是特立独行幸福。 输入样例 2: 110 120 输出样例 2: SAD
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值