您的位置:首页 > 其它

hdu 4149 magic potion 位运算

2015-07-28 16:22 447 查看
题目大意:

用m给x1....x8,8个数字加密,加密方式是x1对m取异或。。。。(x1+...x8)对m取异或。给出加密后的9个数,求m

题解:

设异或之前的数为a1,a2,...a8

异或之后的数为b1,b2...b8

从最后一位往前算

如果b中有奇数个1,那么也就有奇数个0

如果m这一位为0,则有奇数个1,和为1,异或之后的结果为1

如果m这一位为1,则有奇数个0,和为1,异或之后的结果为0

如果b中有偶数个1,那么也就有偶数个0

如果m这一位为0,和为0,异或之后为0

如果m这一位为1,和为0,异或之后为1

从低往高一步步判断,但要注意对进位的处理

从一开始需要增加一个标志位p,初始化为0。

假设m为1,b中有奇数个1,那么做完以上计算之后要把b为1的个数加到p上,同时在下一次运算的时候将p右移。

由于增加了标志位,那么判断相加结果的时候就不只是原来的那个数,还应该考虑当前p的最低位。

#include<iostream>

#include<sstream>

#include<fstream>

#include<vector>

#include<list>

#include<deque>

#include<queue>

#include<stack>

#include<map>

#include<set>

#include<bitset>

#include<algorithm>

#include<cstdio>

#include<cstdlib>

#include<cstring>

#include<cctype>

#include<cmath>

#include<ctime>

#include<iomanip>

#define maxn 55

#define rep(i,n) for(i=1;i<=n;i++)

using namespace std;

int a[10];

int main()

{

int m, p,i,t;

cin >> t;

while (t--)

{

rep(i,9) scanf("%d", &a[i]);

m = 0,p=0;

int k = 0;

while (1)

{

rep(i, 8)

if (a[i] != 0) break;

p >>= 1;

if (i>8 && p == 0 && a[9] == 0) break;

int cnt = 0;

rep(i, 8)

if (a[i] & 1) cnt++;

int y = (cnt & 1);

int z = ((a[9] & 1) + (p & 1)) & 1;

int b = y^z;

if (b)

p += (8 - cnt);

else

p += cnt;

m += (b << k);

k++;

rep(i,9) a[i] >>= 1;

}

cout<<m<<endl;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: