hdu4149 Magic Potion

2018/02/27 16:59
阅读数 56

Magic Potion

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 488    Accepted Submission(s): 287


Problem Description
In a distant magic world, there is a powerful magician aswmtjdsj. One day,aswmtjdsj decide to teach his prentice ykwd to make some magic potions. The magic potion is made by 8 kinds of materials, what aswmtjdsj need to do is to tell ykwd how many each kind of materials is required. In order to prevent others from stealing these formulas, he decide to encrypt the formula. Assuming the amount of the eight kinds of materials are x1, x2, ... x8, aswmtjdsj will use a number m to encrypt, and finally tell ykwd nine numbers:x1 xor m, x2 xor m ,...., x8 xor m, (x1 + x2 +...+ x8) xor m . ykwd is too lazy,however,to calculate the value of the number m, so he asks you to help him to find the number m.

 

 

Input
The first line is an integer t, the number of test cases.
Each of the next t lines contains 9 integers, respectively, x1 xor m, x2 xor m ,...., x8 xor m, (x1 + x2 +...+ x8) xor m, each of the 9 numbers is less or equal to 2 31-1.
 

 

Output
For each test case you should output the value of m in a single line, you can assume that 0 <= m <= 2 31-1.
 

 

Sample Input
2 1 2 3 4 5 6 7 8 36 5 5 5 5 5 5 5 5 123
 

 

Sample Output
0 11
Hint
The XOR operation takes two bit patterns of equal length and performs the logical XOR operation on each pair of corresponding bits. The result of each digit is 1 if the two bits are different, and 0 if they are the same. For example: 0101 (decimal 5) XOR 0011 (decimal 3) = 0110 (decimal 6)
 
刚开始接触这种题时, 一点头绪都没有,但是通过自己查资料,写几个简单的案例模拟一下过程,其实还是很容易理解的。
一下子没想出来没有关系,多试试总会有答案。
主要是弄清楚异或运算 其实和位运算有关系的,将数字转换为二进制自己试试,思路会清晰多。

//x << N: 左移N位就相当于原数乘以2的N次方; x >> N : 右移N位 就相当于原数除以2的N次方。
//x 异或 m,设 y = x << m, 即 y 就等于将x 左移(<<) m 位 ,这点很重要!
//设原来的数字为 xi 与 m 异或后 xi ^m = bi(1 <= i <= 9), (x1+x2+...+x8)^ m = b9 相当于(b1+b2+...+b8) = b9;
//因此 将(b1+b2+...+b8) 每一位与b9的每一位比较,若不相同, 即 意味着原数向左移了 j 位 ,将移动的位数相加即为 m的值
//很容易想到 若xi没有移位的话, (b1+b2+...+b8)^m == b9
#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
  int t;
  int sum, m, tmp;
  cin >> t;
  while(t--)
  {
    int r[10];
    for(int i = 1; i <= 9; i++)
    {
      cin >> r[i];
    }
    sum = m = 0;
    for(int j = 0; j <= 31; j++)
    {
      tmp = 0;
      for(int k = 1; k <= 8; k++)
      {
        tmp += r[k]>>j&1; //(r[k] / 2^j) & 1, 与m异或后的八个数的和 从右至左 取出它的值,与第九个数的第j位比较
      }
      if((sum + tmp)%2 != (r[9]>>j&1))//若不同,将其转换为原数的第i位具有的值, 再求出它的进位值 ,并将m加上 (1左移相应的位数 j )
      {
        tmp = 8 - tmp;
        sum = (sum + tmp) / 2;
        m += 1 << j; 
      }
      else
      {
         sum = (sum + tmp) / 2;//若相同 将进位的用sum加上去,继续下一位
      }
    }
    cout << m << endl;
  }
  return 0;
}

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部