摘要:就是让你把一个数的二进制凑够32位然后从中间劈开交换,再转换成十进制。
我一开始写这道题的时候,思路就是很暴力的把他们拆开,补零,交换转成10进制(用了好多字符串)。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; unsigned long long a,ans=0,sum=0,shi=0; string h,l,hh,ll,ha;//这是一堆字符串 int main(){ scanf("%u",&a); while(a>0){ if(sum<16){//判断如果现在的位数小于16 h[ans]=a%2+'0';//就把这个存在字符串h里面 } if(ans==16){ ans=0;//ans起到的是下标的作用 } if(sum>=16){//判断如果现在的位数小于16 l[ans]=a%2+'0';//就把这个存在字符串h里面 } a/=2; ans++; sum++; } if(sum>=16&&ans<16){//补零 for(int i=ans;i<16;i++){ l[i]='0';//我也不知道我当时怎么想的,好像是觉得两个如果都没有满16,那就做两个判断,都补上零。 } } if(sum<16&&ans<16){//依然是补零 for(int i=ans;i<16;i++){ h[i]='0'; } for(int i=0;i<16;i++){ l[i]='0'; } } sum=0;//用字符串ha把他们两个交换着存过来 for(int i=16-1;i>=0;i--){ ha[sum]=h[i]; sum++; } for(int i=16-1;i>=0;i--){ ha[sum]=l[i]; sum++; } ans=1; sum=0; int i=0; for(int i=32-1;i>=0;i--){//倒着把他们输出出来 shi+=(ha[i]-'0')*ans; ans*=2; } printf("%u",shi); return 0; }
结果很悲惨,不仅没A只得了90不说,我改来改去都把自己给改迷糊了。于是我就重新构思了一下,写了下面的代码,就AC了。
#include<iostream> #include<cstdio> using namespace std; unsigned long long n,shu[10010],ans=0,shi=0; int main(){ scanf("%u",&n); while(n>0){//转二进制,没有用一个字符串,用的数组。因为数组不仅很方便,甚至连补零那一步都省了,因为数组它本身默认值就是0嘛,所以就可以直接转成十进制。 shu[ans]=n%2; n/=2; ans++; } ans=1; for(int i=16;i<32;i++){ shi+=shu[i]*ans; ans*=2; }//先把后面的16位转成10进制。 for(int i=0;i<16;i++){ shi+=shu[i]*ans; ans*=2; }//再把前面的16位转成10进制,记得要用一个变量,不然就变成两个数了 printf("%u\n",shi);//最后输出就好啦 return 0; }
重写的代码:大致思路就是把转化成的二进制存到一个数组里(因为数组默认都是0,所以就直接省去补零这一步了,直接算就好了),一定要记得先算后面的再算前面的!!
做完不久后我又知道了一个东西:左移和右移运算符(跟异或是一套的)
仅仅只用几行就可以把这道题A掉。
代码如下:
#include<iostream> #include<cstdio> int n; int main(){ scanf("%d",&n); printf("%d\n",(n>>16)+(n<<16)); //>>是把这个数转为二进制右移(而且他还会自动补零!!) //<<相反就是把这个数的二进制往左移喽(依然会自动补零) return 0; }
加上注释一共10行,所以建议追求代码简洁的一定要去学学位运算,可以省去好多劲儿。
虽然这个这么简单的代码把我写了好久的代码给秒杀了,但是我并不是很伤心,因为学会了这个以后肯定在别的地方可以用到。