洛谷P1100 位运算+进制转换解释

洛谷P1100 位运算+进制转换解释

AC代码如下:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
	unsigned int a;
	cin>>a;
	cout<<(a>>16)+(a<<16)<<endl;
	return 0;
}

你没有看错,就是这么简单,就是这么酸爽,上个月写的70行代码记忆犹新…


先聊聊二进制吧
总所周知,计算机的记录方式是二进制记录,即计算机的世界是0和1的世界。但我们现实生活却属于十进制的世界,那么如何将十进制转化为二进制呢?
实现代码如下:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int s[100];
int main()
{
	int i=-1;
	unsigned int n;
	cin>>n;
    while(n)
    {
    	s[++i]=n%2;
    	n=n-s[i];
    	if(n/2==0)
    	break;
    	else n=n/2;
	}
	for(int j=i;j>=0;j--)
	cout<<s[j]<<' ';
	cout<<endl;
	return 0;
}

如果单看这段代码实际上是比较抽象的,但当你了解如何将二进制转化为十进制就懂了!
比如说:
5=101=((1*2)+0)*2+1
那么在十进制转二进制中:
过程一:
5%2=1 这个1 就相当于上面式子的最后一个1。
5-1=4
4/2=2
过程二:
2%2=0 这个0就相当于括号内的那个0。
2-0=2
2/2=1
过程三:
1%2=1 这个1相当于开始的那个1。
1/2=0 结束循环。
所以5的二进制是101
二进值转十进值代码如下:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int main()
{
	int sum=0;
	char s[100];
	gets(s);
	int len=strlen(s);
	for(int i=0;i<len;i++)
	{
		sum=sum*2+s[i]-'0';
	}
	cout<<sum<<endl;
	return 0;
 } 

在聊完二进制后再聊聊 unsigned
以前总是可以看到一些大佬的代码里有 unsigned int ans 这个定义,一开始我还是不太了解为什么要定义一个unsigned,直接int不好吗,但学了位运算后明白的彻底。
首先必须知道 int的有效位数是32位,long long的位数是64位。
32位的意义是用二进制存储可以用32个1,即 1111…111 但是int定义的最大位应该是31位,因为最前面的那一位是符号判断位,如果是0,就是正数,如果是1则表示负数。
而如果用unsigned int 则最大位可以达到32位,因为最前面的那一位不用用来当成符号判断位了。


知道了这些后,就应该要学会位运算了

位运算的功能强大到可怕,我也是一知半解,但我发现一篇很好的文章,就直接引用了:

https://blog.csdn.net/deaidai/article/details/78167367


最后再聊回题目本身

给出一个小于32位的正整数。这个数可以用一个3232位的二进制数表示(不足3232位用00补足)。我们称这个二进制数的前1616位为“高位”,后1616位为“低位”。将它的高低位交换,我们可以得到一个新的数。试问这个新的数是多少(用十进制表示)。

例如,数13145201314520用二进制表示为0000 0000 0001 0100 0000 1110 1101
100000000000000101000000111011011000(添加了1111个前导00补足为3232位),其中前1616位为高位,即0000
0000 0001 01000000000000010100;后1616位为低位,即0000 1110 1101
10000000111011011000。将它的高低位进行交换,我们得到了一个新的二进制数0000 1110 1101 1000 0000
0000 0001
010000001110110110000000000000010100。它即是十进制的249036820249036820。

这题有坑,如果你是先把十进制转化为二进制,再调换位置,再将二进制转化为十进制的,那么你已经输了一半了。
我再次强调,在计算机里,存储是二进制存储,那么即使你输入的是一个十进值的数,它在计算机里表达的还是二进制,所以你只需要通过位运算模拟题目就行。所以本题AC代码简短到令人害怕。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值