题目分析
在3n+1的猜想基础上,要求分离出数列中的关键数字。做法就是对于数列中的每一个数字都进行3n+1猜想中的验证,记录过程中间出现的数字。凡是作为中间数出现在验证过程中的数列中的数都是被覆盖的数,予以标记。最后剩下的未被覆盖的就是关键数字,再按照某种算法从大到小输出即可。
算法实现
用两个数组来完成筛选和排序的过程。一个int num[maxn]
用于读入数列中的元素,一个bool num_flag[maxn]
用于标记每个数字是否被覆盖,初始化全为false
表示未覆盖。
对于num
数组,遍历之,对其每个元素做3n+1猜想,并将计算过程每个中间数对应的num_flag
位标记为true
,猜想的计算过程可以递归完成。遍历完后num_flag
中被覆盖的数对应位为true
,关键数字和非num
数组中的数对应的标记位为false
。
为实现从大到小排序,用下标i
从maxn-1
到0
进行循环,对每个i
检查其是否为num
中的数,如果是的话再检查i
对应的标记位是否为false
,若是则为关键数字。
输出格式要求末尾没有额外空格,因此用一个开关量bool first = true
来辨别当前是否为第一个输出的数字,如果是就直接输出并令first = false
。对于后续不是第一个输出的数字则先输出空格再输出关键数字。
代码
1 |
|
踩坑指南
需要注意,对于num
中的数,在第一次传入递归函数时不要对其进行标记,未保持递归函数的可重载性,额外设置一个参数bool org
,对于数列中的数首次对其遍历时令org = true
,递归调用时令org = false
。
转载请注明来源:©Tinshine