PAT乙级-1005-继续(3*n + 1)猜想
卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里,情况稍微有些复杂。
当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对 n=3 进行验证的时候,我们需要计算 3、5、8、4、2、1,则当我们对 n=5、8、4、2 进行验证的时候,就可以直接判定卡拉兹猜想的真伪,而不需要重复计算,因为这 4 个数已经在验证3的时候遇到过了,我们称 5、8、4、2 是被 3“覆盖”的数。我们称一个数列中的某个数 n 为“关键数”,如果 n 不能被数列中的其他数字所覆盖。
现在给定一系列待验证的数字,我们只需要验证其中的几个关键数,就可以不必再重复验证余下的数字。你的任务就是找出这些关键数字,并按从大到小的顺序输出它们。
输入格式
每个测试输入包含 1 个测试用例,第 1 行给出一个正整数 K (<100),第 2 行给出 K 个互不相同的待验证的正整数 n (1<n≤100)的值,数字间用空格隔开。
输出格式
每个测试用例的输出占一行,按从大到小的顺序输出关键数字。数字间用 1 个空格隔开,但一行中最后一个数字后没有空格。
输入样例
6
3 5 6 7 8 11
输出样例
7 6
解题思路
用输入样例中的数进行递推可发现:
3 递推: ->5->8->4->2->1
5 递推: ->(在3递推中已出现5)
6 递推: ->3
7 递推: ->11->17->->26->13->20->10->5
8 递推: ->
11递推 :->
经观察可发现,关键数字在递推中不会出现(输入样例中的6,7),而其余数(3, 5, 8, 11)均会在递推过程中复现。
因此:
可以设置一个数组arr[10000 ],递推过程中出现的数n,可将其对应的下标数设为1来标记,即:
//递推中出现的数标记为0
arr[n] = 1;
//以样例数n作为下标,若arr[n] != 1,则说明n是关键数
这样最终将输入样例作为下标,把数组arr[ ]中不为1的项输出即可。
注意:题目要求从大到小输出,所以最后进行一个排序。
这里采用algorithm库下的sort方法。
有两种写法
法1:
bool cmp(int a, int b) {return a > b;}
sort(v.begin(), v.end(), cmp);
法2:
sort(v.begin(), v.end(), greater<int>());
完整代码
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int arr[10000];
bool cmp(int a, int b) {return a > b;}
int main() {
int k, n, flag = 0;
cin >> k;
vector<int> v(k);
for (int i = 0; i < k; i++) {
cin >> n;
v[i] = n;
while (n != 1) {
if (n % 2 != 0) n = 3 * n + 1;
n = n / 2;
// 每个数字n用数组中arr[n]记录,当运算过程中出现了,就将值设成1
if (arr[n] == 1) break;
arr[n] = 1;
}
}
/**
* 输入:6
3 5 6 7 8 11
* 经过sort排序后,v[5] = {11, 8, 7, 6, 5, 3}, size = 6;
* 通过找规律可以发现,凡是一组数中的关键数,在递推过程中不会出现
* 例如上述输入的梯队过程如有:
* 3->5->8->4->2->1
* 5->
* 6->3
* 7->11->17->->26->13->20->10->5
* 8->
* 11->
*
* 在给梯队过程中出现的每一个数n,设置arr[n] = 1的过程中
* 初始数不会计入,即3->5->8...这一项,arr[3]不会改变,是从arr[5] = 1开始的
*
* 所以关键数的arr[n] = 0
* 所以当v[i]为关键数时,
* arr[v[i]] = 0;
*/
//排序是因为题目要求从大到小输出
//也可以这样写:
//sort(v.begin(), v.end(), greater<int>());
sort(v.begin(), v.end(), cmp);
for (int i = 0; i < v.size(); i++) {
if (arr[v[i]] == 0) {
if (flag == 1) cout << " ";
cout << v[i];
flag = 1;
}
}
return 0;
}
参考:
柳婼:https://www.liuchuo.net/archives/455