原代码:吉大秦少游大佬的文章,这是原文地址。
个人理解(注释)
//考虑哈希散列方法
//每一个InputNum,会将其覆盖数全部置1;
//每一个输入数字的序号对应一个InputNum.
//因此只要每一个输入数字序号对应的数字的散列数组值仍然为0,
//就说明不是覆盖数,就可以输出。
//或许可以用图论的思想理解
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int arr[10000];//全0数组,表示都没有被覆盖的状态
bool cmp(int a, int b) {return a > b;}
int main() {
int k, n;
cin >> k;
vector<int> v(k);
for (int i = 0; i < k; i++) {
cin >> n;
v[i] = n;//存放输入数据
while (n != 1) {
//寻找n的覆盖数(体现为arr中的位置)
if (n % 2 != 0) n = 3 * n + 1;
n = n / 2;
if (arr[n] == 1) break;//该数已被其他数覆盖
arr[n] = 1;
//注意,n的位置没有被它本身覆盖
//算法的关键在于寻找输入数有没有被【其他数】覆盖
//如果被覆盖,那么它不是关键数
}
}
sort(v.begin(), v.end(), cmp);//很好用的排序工具
int space=0;//交替输出空格
for (int i = 0; i < v.size(); i++) {
if (arr[v[i]] == 0) {
if (space == 1) cout << " ";
cout << v[i];
space = 1;
}
}
return 0;
}