PAT1005乙级部分测试点失败的原因分析
PAT1005题目链接
https://pintia.cn/problemsets/994805260223102976/problems/994805320306507776
题解
题目思路并不复杂,但有几个注意点:如果测试数组内只有单独的1,那么1就是关键数;还有就是最后一个测试点里有100这个数,在某种方法下数组定义太小可能会越界。
第一种思路
用两个数组分别来记录下标为n的时候是否为输入的数和是否为关键数,最后取交集从大到小输出。
#include"iostream"
#include"algorithm"
using namespace std;
bool cmp(int x, int y) {//sort函数的比较函数
return x > y;
}
int main() {
int k,n;
cin >> k;
int *ifk = new int[300]();//记录是否是为输入的数,i是输入的数if[i]就为1
int *ifkey = new int[300];//记录是否为关键数,i是关键数ifkey[i]为1
fill(ifkey, ifkey + 300, 1);
for (int i = 0; i < k; i++) {
cin >> n;
ifk[n] = 1;
int x = (n % 2 == 0 ? n / 2 : (3 * n + 1) / 2);
while (x != 1) {
ifkey[x] = 0;
x= (x % 2 == 0 ? x / 2 : (3 * x + 1) / 2);
}
}
bool iffirst = true;
for (int i = 100; i >=0; i--) {
if (ifkey[i] == 1 && ifk[i] == 1) {
if (iffirst) {
cout << i;
iffirst = false;
}
else cout <<' '<< i;
}
}
return 0;
}
第二种思路
相比上一种减少了内存的分配,记录是否为关键数的数组ifkey[i]并不是记录下标为 i 时的数是否为关键数,而是直接记录n[i]是否为关键数。
#include"iostream"
#include"algorithm"
using namespace std;
bool cmp(int x, int y) {//sort函数的比较函数
return x > y;
}
int main() {
int k;
cin >> k;
int *n = new int[k];//存储输入的正整数
int *ifkey = new int[k];//记录n[i]是否为关键数,初始为1,被覆盖为0
fill(ifkey, ifkey + k, 1);
for (int i = 0; i < k; i++) {
cin >> n[i];
}
sort(n, n + k, cmp);//先对n数列进行从大到小排序,便于之后输出
for (int i = 0; i < k; i++) {
if (ifkey[i] == 0) continue;//被覆盖就计算下一个数
if (n[i] == 1 && k != 1) ifkey[i] = 0;
int x = n[i];
while (x != 1) {
if (x % 2 == 0) x = x / 2;
else x = (3 * x + 1) / 2;
for (int j = 0; j < k; j++) {//将经历的数标记为被覆盖
if (n[j] == x) ifkey[j] = 0;
}
}
}
bool iffirst = true;
for (int i = 0; i < k; i++) {//输出
if (ifkey[i] == 1) {
if (iffirst) {
cout << n[i];
iffirst = false;
}
else cout << ' ' << n[i];
}
}
return 0;
}
感谢
@臭咸鱼:https://www.cnblogs.com/chouxianyu/
@和蔼的没有巴:https://tieba.baidu.com/p/4938600293
的作品对本人的帮助。