uoj #2 NOI2014起床困难综合症 贪心+位运算

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uoj #2 NOI2014起床困难综合症 贪心+位运算相关的知识,希望对你有一定的参考价值。

题目链接

给出n个数, 每个数有特定的一种操作, &|^三种, 给出一个m, 初始值属于[0,m],选定一个初始值, 使所有操作做完之后的值最大, 输出这个最大值。

1, 从最高位贪心, 如果初始这一位为0的时候, 所有操作进行完之后结果为1, 那么这一位就已经确定位0。

2, 初始为0, 如果所有操作进行完之后这一位为0, 那么就试初始为1的条件。 设当前位是第pos位, 如果之前已经有的数加上(1<<pos)小于m, 那么这一位为1就是可以的。 当初始为1的时候, 所有操作进行完之后, 如果为1, 那么就将这一位确定为1, 否则这一位为0。

具体看代码。

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1061109567;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
int m, ans, n, digit[100005][32];
char c[100005][4];
void cal(int num, int flag) {
    int x = 0;
    for(int i = 0; i<n; i++) {
        if(c[i][0] == A) {
            x &= digit[i][num];
        } else if(c[i][0] == O) {
            x |= digit[i][num];
        } else {
            x ^= digit[i][num];
        }
    }
    if(x) {
        ans += (1<<num);
        return ;
    }
    if(flag) {
        x = 1;
        for(int i = 0; i<n; i++) {
            if(c[i][0] == A) {
                x &= digit[i][num];
            } else if(c[i][0] == O) {
                x |= digit[i][num];
            } else {
                x ^= digit[i][num];
            }
        }
        if(x == 1) {
            ans += (1<<num);
            m -= (1<<num);         
        }
    }
}
int main()
{
    int x;
    cin>>n>>m;
    for(int i = 0; i<n; i++) {
        scanf("%s%d", c[i], &x);
        int num = 0;
        while(x) {
            digit[i][num++] = x&1;
            x>>=1;
        }
    }
    for(int i = 30; i>=0; i--) {
        int flag = 0;
        if((1<<i)<=m)
            flag = 1;
        cal(i, flag);
    }
    cout<<ans<<endl;
    return 0;
}

 

以上是关于uoj #2 NOI2014起床困难综合症 贪心+位运算的主要内容,如果未能解决你的问题,请参考以下文章

uoj #2 NOI2014起床困难综合症 贪心+位运算

BZOJ3668/UOJ2 [NOI2014]起床困难综合症

uoj2 NOI2014—起床困难综合症

[NOI2014]起床困难综合症

NOI2014起床困难综合症(贪心)

noi2014 起床困难综合症