解题报告 『[NOI2014]起床困难综合症(位运算)』
虽说是NOI的题目,但其实并不难,所以解析我就写在代码里了。
代码实现如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//本题应首先将数拆为二进制. #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (register int i = (a); i <= (b); i++) #define per(i, a, b) for (register int i = (a); i >= (b); i--) int n, m, x, a1 = 0, a2 = -1, ans = 0;//a1表示000...0,a2表示111...1,所以用int或unsigned int都行. char opt[5]; int read() { int x = 0, flag = 0; char ch = ' '; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar(); if (ch == '-') { flag = 1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); } return flag ? -x : x; } void write(int x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x / 10); putchar(x % 10 + '0'); } int main() { n = read(), m = read(); rep(i, 1, n) { scanf("%s", opt), x = read(); if (opt[0] == 'A') { a1 &= x; a2 &= x; } if (opt[0] == 'O') { a1 |= x; a2 |= x; } if (opt[0] == 'X') { a1 ^= x; a2 ^= x; } } per(i, 31, 0) { if (a1 >> i & 1) ans += 1 << i;//能将0变为1,何乐而不为? else if (a2 >> i & 1 && (1 << i) <= m) {//注意这里用的是else if. ans += 1 << i; m -= 1 << i; }//能将1变为1,就变,反正也没损失. } write(ans); return 0; }