!HDU 4149 Magic Potion-yy-(二进制位运算技巧)

题意:已知九个数:x1 xor m,x2 xor m......x8 xor m,(x1+x2+....+x8) xor m;求出m

分析:

1.深入了解运用位运算:加法、异或的特性。异或的一些特性如:异或偶数次同样的数等于没做任何操作;若 a=b^c 则:b=a^c 、c=a^b

2.熟练运用位运算符号:& 和 ^   比如用 &1 从十进制的角度可以判断一个数是奇数还是偶数,从二进制位的角度也可以得到一个数的最末位是1还是0

3.理解运用一位运算符:>> 和 <<

这道题是从低位开始一位一位的计算。主要思路是计算这八个数的最末位为1的数的个数记为 cnt ,再加上进位(初始设为0)设和为 x, 如果x是奇数,则这八个数加起来的和的末位也一定是1;如果是偶数,则末位一定是0,。这时候再根据已知的这八个数的和异或m的值得末位就可以反推出m的末位(用上面的异或的特性二)然后这九个数都右移一位,进位也右移一位,即把高位的移到末位,然后循环,直到所有数都为0且进位也为0.

不清楚就好好想想。

代码:

#include<cstdio>
#include<iostream>
#define INF 1<<31
using namespace std;
int t,a[10];
int main()
{
      cin>>t;
      while(t--){
      	for(int i=0;i<9;i++) cin>>a[i];
      	int c=0,m=0;
      	int k=0;
      	while(1){
      		int pp;
      		for(pp=0;pp<9;pp++)
      		  if(a[pp]!=0) break;
      			c>>=1;            // 位运算进位跟着移动 
      		if(!c&&pp==9) break;	
      		int cnt=0;
      		for(int i=0;i<8;i++) if(a[i]&1) cnt++;  // &1判断奇偶 
      		int x=cnt&1;
      		int y=(x^(c&1)^(a[8]&1));  //异或运算的循环特性 
      		if(y){
      			c+=8-cnt;  //求出原来的数中真正的1的个数得到进位 
      		}
      		else c+=cnt;
      		m+=y<<k;            // <<运算符的运用 
      		k++;
      		for(int i=0;i<9;i++) a[i]>>=1;   //位运算时常用的移动 
      	}
      	cout<<m<<endl;
      }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值