PTA L2-029 | 特立独行的幸福 (打表+递归)
题目描述
对一个十进制数的各位数字做一次平方和,称作一次迭代。如果一个十进制数能通过若干次迭代得到 \(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;
}
PTA L2-029 | 特立独行的幸福 (打表+递归)的更多相关文章
- 2019年GPLT L2-1 特立独行的幸福 比赛题解 中国高校计算机大赛-团体程序设计天梯赛题解
对一个十进制数的各位数字做一次平方和,称作一次迭代.如果一个十进制数能通过若干次迭代得到 1,就称该数为幸福数.1 是一个幸福数.此外,例如 19 经过 1 次迭代得到 82,2 次迭代后得到 68, ...
- L2-029 特立独行的幸福 (25 分)
L2-029 特立独行的幸福 (25 分) 对一个十进制数的各位数字做一次平方和,称作一次迭代.如果一个十进制数能通过若干次迭代得到 1,就称该数为幸福数.1 是一个幸福数.此外,例如 19 经过 ...
- PTA刷题笔记
PTA刷题记录 仓库地址: https://github.com/Haorical/Code/tree/master/PTA/GPLT 两周之内刷完GPLT L2和L3的题,持续更新,包括AK代码,坑 ...
- redis 系列7 数据结构之跳跃表
一.概述 跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.在大部分情况下,跳跃表的效率可以和平衡树(关系型数据库的索引就是平衡树 ...
- week2--线性表
一.PTA实验作业 题目1:顺序表删除重复元素(6-3) 设计思路 代码截图 PTA提交列表说明 编译错误:写'->'符号的时候总是漏掉'>'; 写'!='符号的时候漏写'!'; 解决方法 ...
- week-02 线性表
一.PTA实验作业 题目1:顺序表 7-1 最长连续递增子序列 1. 设计思路 定义结构体List,定义数组Data[maxsize]表示顺序表元素,变量Position表示位置,变量Length表示 ...
- SDNLAB技术分享(四):利用ODL下发流表创建VxLAN网络
邓晓涛,当前就职于江苏省未来网络创新研究院,是CDN团队的一名研发人员,主要从事SDN相关的研发相关工作.曾就职于三星电子于先行解决方案研发组任高级工程师.思科系统于云协作应用技术部(CCATG)任工 ...
- SqlServer 三级联动、递归表
SqlServer 省市县三级联动 三张表递归合并成一张表sql如下: insert into table2(area_name,area_parent_id) select province,'0' ...
- Java: 实现顺序表和单链表的快速排序
快速排序 快速排序原理 快速排序(Quick Sort)的基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可对这两部分记录继续进行排序,以达到 ...
随机推荐
- 基于 Google-S2 的地理相册服务实现及应用
马蜂窝技术原创内容,更多干货请关注公众号:mfwtech 随着智能手机存储容量的增大,以及相册备份技术的普及,我们可以随时随地用手机影像记录生活,在手机中存储几千张甚至上万张照片已经是很常见的事情.但 ...
- 高精度模板(Vector实现更加方便)
计算的数long long 甚至更大的数据类型的都存不下的时候,应该怎么办 ? 解决方法 :我们可以把一个很大的数当做字符串进行处理,这时候就需要用到高精度. 话不多说,咱们边看代码边处理 : 加法 ...
- Codeforces Round #617 (Div. 3) D. Fight with Monsters
D : Fight with Monsters 题目大意 : 有一组数,每个值对应着一个怪物的 hp 值,现在有两个人,一个自己一个对手,每个人有一个攻击值, 两个人轮流攻击怪物,如果是自己将怪物先打 ...
- python学习(7)关于列表操作相关命令以及浅复制深复制
在python中,[]表示的是列表.列表有各种操作命令. 1.append()方法,添加一个元素到列表尾部. 注意append()方法与extend()方法有区别:list.append(object ...
- 写ppt的助手
代码格式化工具. https://carbon.now.sh/?bg=rgba(74%2C144%2C226%2C1)&t=material&wt=none&l=auto&am ...
- MySQL中的索引、左连接、右连接、join、sql执行顺序
逻辑架构: 1.连接层 2.服务层 3.引擎层(插拔式) 4.存储层 存储引擎: 常用的有:MyISAM.InnoDB 查看命令:show variables like '%storage_engin ...
- centos7下NAT模式下设置静态ip
1.在虚拟网络编辑器下查看子网IP.子网掩码以及网关 2.在Linux系统中进入 /etc/sysconfig/network-scripts目录下,编辑ifcfg-ens33文件,改成下面的内容: ...
- VBA-FileToFileUpdate
Public Sub FileToFileUpdate(ByVal fileName As String, ByVal strFrm As String, ByVal strTo As String) ...
- ggEditor流程图增加网格背景
参考官方文档: https://www.yuque.com/antv/g6/plugin.tool.grid react-ggEditor如何使用 import { Flow } from 'gg-e ...
- NIO学习笔记,从Linux IO演化模型到Netty—— Linux零拷贝
这里只是感性地认识Linux零拷贝,不涉及具体细节. 1.Linux传统的数据拷贝 用户进程是不能直接访问文件系统的,要先切换到内核态,发起系统调用,DMA把磁盘中的数据写入内核空间,内核再把数据拷贝 ...