卡拉兹(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
了解题意后我们可以知道,我们需要找到与每次处理后的数不同的你所输入的数,并按降序输出。
于是很自然的就能想到,我们可以先把我们所输入的数用一个数组存起来,然后我们再把每次处理后的数用一个数组把它给存起来,最后进行比较找出不同的数并再用一个数组把它们存起来,最后再按题目要求降序输出即可
这里主要想要介绍一种可以直接把数组进行升降序排序的方法:
①写好头文件:#include 《algorithm》(写尖括号我的文章会显示不出来此头文件)
②再写:
升序:sort(a,a+sizeof(a)/sizeof(a[0])) a为数组名
降序:sort(a,a+sizeof(a)/sizeof(a[0]),greater<数组元素类型>())
写好这些后,数组内的元素就已经排序完成了
#include <iostream> #include <algorithm> using namespace std; void deal(int n_);//用来处理你所输入的数的函数 int a[10000] = { 0 };//要尽量把每次处理后的数给存起来的数组的大小设置大一些以防止溢出情况 int a_num = 0;//用以记录数组a的元素个数,方便后续处理 int main() { int n; cin >> n; while (n >= 100)//保证正确输入 { cin >> n; } int b[120] = { 0 };//用以存储我们所输入的数 int b_num = 0;//用以记录数组b的元素个数,方便后续处理 int c[120] = { 0 };//用以存储数组a与数组b不同的数 int c_num = 0;//用以记录数组c的元素个数,方便后续处理 while (n--) { int temp; cin >> temp; while (temp <= 1 || temp > 1000)//保证正确输入 { cin >> temp; } b[b_num] = temp;//把我们所输入的数用这个数组存起来 b_num++; deal(temp);//把我们所输入的数用deal函数处理 } for (int i = 0; i < b_num; i++) { for (int j = 0; j < a_num; j++) { if (a[j] == b[i])//找到与处理后的数相同的数并将此数改为0 { b[i] = 0; break; } } } for (int i = 0; i < b_num; i++)//当数组b中的数不为0时我们就用数组c来存这个不为0的数 { if (b[i] != 0) { c[c_num] = b[i]; c_num++; } } sort(c, c + c_num, greater<int>());//对数组c进行降序排序 for (int i = 0; i < c_num - 1; i++)//按题目要求输出 { cout << c[i] << " "; } cout << c[c_num - 1] << endl; } void deal(int n_) //用来处理你所输入的数的函数 { while (n_ != 1) { if (n_ % 2 == 0) { n_ = n_ / 2; a[a_num] = n_; a_num++; } else { n_ = (3 * n_ + 1) / 2; a[a_num] = n_; a_num++; } } }