题目描述

对一个十进制数的各位数字做一次平方和,称作一次迭代。如果一个十进制数能通过若干次迭代得到 \(1\),就称该数为幸福数。\(1\) 是一个幸福数。此外,例如 \(19\) 经过一次迭代得到 \(82\) ,二次迭代后得到 \(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

输入 #2

110 120

输出 #2

SAD

说明/提示

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

————————————————————————————————————

首先会想到把每个数字抽象成节点,每个节点根据题目给的迭代方式连接到后继节点上。

由于这个过程是难逆的,而在某数不断迭代之后只可能有两个结果。

(1)变换成数字 \(1\),路径上都是幸福数 (2)出现环,路径上都是不幸福数

所以我们不妨把数字 \(1\) 所在节点视为根节点,然后每一次迭代就变成了“找父亲”的过程。

由于父亲幸福或不幸福会影响到儿子(父亲依赖于儿子),所以我们只要在递归中不断让儿子继承父亲的状态再维护一下到根的距离即可。

如果打表一下可以发现只会有一个环出现,即题目给的那个环,但我这里直接忽略了这个直接标记着找环了。

代码如下:

#include <bits/stdc++.h>
#define MAXN 100007
using namespace std;
int a,b,cnt,dep[MAXN],ty[MAXN],prime[MAXN];
bool fl,rd[MAXN],vis[MAXN],isp[MAXN]; //ty = 0 未访问 1 幸福数 2 不幸福数
//rd = true 特立独行(入度为零) false 非特立独行(入度大于零)
//vis 是用来判断环的 vis = 1 表示该元素之前在递归栈中出现过
//dep 保存着到1号节点的深度 即变换成1需要的次数 //线性筛质数 isp 保存一个数是否为质数
//也可以最后用 O(sqrt) 的时间判定质数,但是理论复杂度会上升
inline void init() {
memset(isp,1,sizeof(isp));
isp[0]=isp[1]=false;
for (int i=2;i<MAXN;i++) {
if (isp[i]) prime[++cnt]=i;
for(int j=1;j<=cnt && i*prime[j]<MAXN;j++) {
isp[i*prime[j]]=false;
if (!(i%prime[j])) break;
}
}
} //计算下一次迭代的函数
inline int nxt(int x) {
int ret=0;
while (x) ret+=(x%10)*(x%10),x/=10;
return ret;
} //核心的递归函数
inline void search(int x) {
int to=nxt(x); vis[x]=true; //把出现过的数都用vis标记下 下次如果再遇到这个数即有环(不幸福)
if ((vis[to] && !ty[to]) || ty[to]==2) ty[x]=2; //后继(父亲)若不幸福 当前节点也不幸福
else if (ty[to]==1) ty[x]=1; //后继(父亲)若幸福,当前节点也幸福
else search(to),ty[x]=ty[to]; //后继的状态未知 则递归找一下
rd[to]=true,dep[x]=dep[to]+1; //把有前驱的节点标记成不特立独行的 累加到1(根节点)的深度
} int main() {
init(); ty[1]=1; //初始化 1显然是幸福的
scanf("%d%d",&a,&b);
for (int i=a;i<=b;i++) if (!ty[i]) search(i); //如果状态未知 则递归找一下
for (int i=a;i<=b;i++)
if (ty[i]==1 && !rd[i]) //若同时满足特立独行和幸福
printf("%d %d\n",i,isp[i]?dep[i]*2:dep[i]),fl=true;
if (!fl) puts("SAD"); //SO SAD
return 0;
}

最新文章

  1. Mysql主从复制,读写分离(mysql-proxy),双主结构完整构建过程
  2. linux 网卡启动方法
  3. JS 语言的Function 解析
  4. i++; 与 ++i;的内部区别。
  5. 说说Java中的枚举(一)
  6. c# MVC中 @Styles.Render索引超出下标
  7. 【solr】solr5.0整合tomcat
  8. python中functools.wraps装饰器的作用
  9. 从xcode 6 上传 App Store
  10. linux安装配置solr
  11. ExecutorService的submit(Runnable x)和execute(Runnable x) 两个方法的本质区别
  12. --@angularJS--指令之单个点击展开demo
  13. 当进行服务端渲染的时间,某些npm包可能会调用document,window这些对象而导致报错
  14. vue中连续点击3次且时间间隔不超过3秒,才显示div(刚开始隐藏的)
  15. AtCoder Beginner Contest 043 D - アンバランス / Unbalanced
  16. RAR压缩包审计工具unrar-nofree
  17. ostringstream的用法
  18. MDAC 重新安装
  19. web.xml详细配置
  20. DDD Quickly - 读书笔记

热门文章

  1. (原)NSQ源码阅读和分析(1)
  2. android 基础学习笔记1
  3. python笔记22(面向对象课程四)
  4. python使用turtle库绘制奥运五环
  5. CentOS7.x以上版本配置DNS失效解决办法
  6. [CSS]三大特性之一继承性、层叠性、优先级
  7. JAVA架构之单点登录 任务调度 权限管理 性能优化大型项目实战
  8. cesium结合geoserver利用WFS服务实现图层新增(附源码下载)
  9. idea如何做到多模块开发项目 收藏整理
  10. 修改PR Cs6,PS Cs6,AU Cs6的启动界面