解题报告 『[NOI2014]起床困难综合症(位运算)』

原题地址

虽说是NOI的题目,但其实并不难,所以解析我就写在代码里了。

 

代码实现如下:

//本题应首先将数拆为二进制. 
#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;
}
View Code
posted @ 2019-07-11 19:36  雲裏霧裏沙  阅读(150)  评论(0编辑  收藏  举报