- 【例45.3】 寻找最低数
【例45.3】自研解法 因为感觉不错所以发篇讨论
- 2024-9-28 14:02:03 @
题目:
这题的意思就是把一个数转化为2进制 然后找到从后往前的第一个1 再把1前的数转化为10进制
做这题需要熟练掌握进制转换 因为低进制转高进制和高进制转低进制在这题都有涉及 以下是徐聪明的常规解法:
#include<stdio.h>
#include<math.h>
int main(){
int a;
while(1){
scanf("%d",&a);
if(a==0) break;
int i=0;
int bin[32]={0};
while(a>0){
bin[i]=a%2;
a/=2;
i++;
}
for(int j=0;j<i;j++){
if(bin[j]!=0) {printf("%d\n",(int)pow(2,j));break;}
}
}
return 0;
}
徐聪明解法的主要思路是就是我刚刚说的:
把一个数转化为2进制 然后找到从后往前的第一个1 再把1前的数转化为10进制 有一种模拟算法的感觉
但是这题真的需要把一个数全部转化为2进制吗?
我们再看一遍我写的题目提纲: "找到从后往前的第一个1"
从后往前是重点 在转进制的过程中正是先转的作低位 后转的作高位 而这 与从后往前有异曲同工之妙
因此 我们在转进制的过程中就可以检查 如果这一位为1的话就没必要在转了
以下是代码实现:
int cnt = 0;
while(a > 0) {
if(a % 2 == 0) {
++cnt;
}
else {
break;
}
a /= 2;
}
上述代码中有省去数组空间 节省性能等优点(其实主要是思路帅 代码和优化啥的都没啥改进)
再提一嘴 代码中a是十进制数 cnt是读到1前的位数
是的 我直接记录了1前的位数
因此我不用像老登一样遍历数组检查(虽然我也没有数组)
直接
printf("%d\n",1 << cnt);
就可以了(其实这点也没啥优化 只是简洁了一点)
以上皆为思路 以下是AC代码:
#include<stdio.h>
int main() {
while(true) {
long long a;
scanf("%lld",&a);
if(a <= 0){
return 0;
}
int cnt = 0;
while(a > 0) {
if(a % 2 == 0) {
++cnt;
}
else {
break;
}
a /= 2;
}
printf("%d\n",1 << cnt);
}
}
The End
等等 我是贝利亚 我发现陈锦润这个大杉并写得那么复杂还有脸发讨论 我来帮他纠正一下他的破代码:
#include<stdio.h>
int a;int main(){while(1){scanf("%d",&a);if(!a)break;printf("%d\n",a&-a);}}
看到我贝利亚大王的实力了吧 快把代码拿去用吧 绝对AC
4 comments
-
陈锦润 LV 8 @ 2024-11-19 20:59:42
666贝利亚大王太有实力了
-
2024-10-12 12:59:18@
-
2024-10-7 12:00:12@
牛牛牛,找徐老登领杯奶茶奖励一下
-
2024-9-29 13:56:56@
good!
- 1
Information
- ID
- 196
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 4
- Tags
- # Submissions
- 41
- Accepted
- 19
- Uploaded By