

思路:思路来自
1.这道题大体的意思是把你所给的数列全部都进行卡拉兹猜想,如果所给数列中有进行验证时所有出现的数字,即数字被覆盖,如果没有,便是关键数,如图中例子
3:5 8 4 2 1
5:8 4 2 1
6:3 5 8 4 2 1
7:11 17 26 13 20 10 5 8 4 2 1
8:4 2 1
11:17 26 13 20 10 5 8 4 2 1
6个数字验证猜想时所用的数字都没有6和7 所以输出7 6(从大到小)
2.先定义一个101大小的数组,所有index的value全部定为0,将所输入的几个数字映射为1,然后每一个都进行猜想验证,验证过程中,所出现的数字将该数字作为索引,将其value赋值0,最后只需要输入value为1的索引即可
3.值得注意的一点是,a&&b和b&&a是不同的,逻辑结果相同,但有顺序,如果左边为假便不会进行右边的判断。代码17行,如果先进行a[temp]就会出现temp大于101越界,测试时会出现段错误。而把temp<=100放前面,后面的数组index就永远<=100,便不会发生越界
代码:
#include <stdio.h>
int main(void){
int num,i,temp;
int a[101]={0};//初始化数组
scanf("%d",&num);
for (i=0;i<num;i++){
scanf("%d",&temp);
a[temp]=1;//将输入的数字作为索引,将其值赋为1
}
for (i=0;i<=100;i++){
if ( a[i] ){//value为1的进行卡拉兹猜想
temp=i;
while (temp > 1){
if(temp%2){
temp=(temp*3+1) / 2;
}else{temp/=2;}
if( temp<=100 && a[temp] ){//如果过程中的数字<=100且作为index对应value为1,就映射为0
a[temp]=0;//值得注意的是,必须要temp<=100放在前面,如果a[temp]在前,因为temp是可能大于101的,会发生数组越界
num--;//每覆盖一个数字,数组里剩的数字个数就-1
}
}
}
}
for (i=100;i>=1;i--){
if(a[i]){
printf("%d%c", i,--num?' ':'\n');
}//判断是否输出的为最后一个数,如果是最后一个数就输出换行符
}
return 0;
}
这篇博客探讨了如何使用C语言实现卡拉兹猜想(Collatz Conjecture),通过对给定数列进行猜想验证,找出未被覆盖的‘关键数’。博主通过创建一个101长度的数组来跟踪数字,避免越界问题,并强调了逻辑运算符的顺序影响。
2216

被折叠的 条评论
为什么被折叠?



