美文网首页程序员
BZOJ_3668_起床困难综合症

BZOJ_3668_起床困难综合症

作者: gdjs2 | 来源:发表于2016-03-05 15:01 被阅读39次

About Problem

Solve

题目的意思就是给你一些操作C[1] - C[N],每个操作只有可能是AND(&), OR(|), XOR(^)中的一个。
然后给你一个数M。
设f(x)为 x 经过操作 C[1] - C[N] 后的得到的答案。
要求:


Score 50%

其实这个就很简单的,枚举每一个M,然后去跑N个步骤,然后找出最优解就可以。
复杂度O(M * N)

Code:

#include <cstdio>
#include <cstring>

#ifdef _WIN32
#define lld I64d
#endif

const int Maxn = int(1e5) + 10;
int n, m, t[Maxn], com[Maxn];

int ans = 0;
void force1()
{
    for(int i = 0; i <= m; ++i)
    {
        int tmp = i;
        for(int j = 1; j <= n; ++j)
            if(com[j] == 1) tmp = tmp & t[j];
            else if(com[j] == 2) tmp = tmp | t[j];
            else if(com[j] == 3) tmp = tmp xor t[j];
        if(tmp > ans) ans = tmp;
    }
    printf("%d\n", ans);
    return;
}

int main()
{
    freopen("sleep.in", "r", stdin);
    freopen("sleep.out", "w", stdout);
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; ++i)
    {
        char s[5];
        scanf("%s %d", s, &t[i]);
        if(s[0] == 'A') com[i] = 1;
        else if(s[0] == 'O') com[i] = 2;
        else if(s[0] == 'X') com[i] = 3;
    }
    if(m <= 1000) force1();
    return 0;
}

Score 100%

既然M高达1e9,那么很明显不能枚举M了。
那我们换个思路,既然这里都是二进制计算,那么这些二进制计算有一个非常显著的特点,就是它的每一位都是相对独立的。
举个例子来说:

6 = 1 1 0
5 = 1 0 1
6 ^ 5 = 0 1 1
当你在计算从左往右数第2位时, 第一位和第三位均不会影响第二位的运算结果。

我们假设最后的答案是从 K 经过N步后得到的 f(K)。
那么我们是不是可以枚举 K 的每一个二进制位,然后看 K 的第 i 个二进制位为1更优 还是为0更优。
最后得到每一个二进制位的最有值,在贪心选取,看看得到的K会不会超过M。
再求出f(K)就OK了。
由于答案在1e9内,所以不会超过32位。
每位可以进行N次操作,所以复杂度为O(32 * N)

Code:

#include <cstdio>
#include <cstring>

const int Maxn = (int)1e5 + 10;
int num[Maxn][40], t[Maxn], ans[40];
int N = 0;

int main()
{
    freopen("sleep.in", "r", stdin);
    freopen("sleep.out", "w", stdout);
    
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; ++i)
    {
        char s[5];
        scanf("%s %d", s, &t[i]);
        if(s[0] == 'A') num[i][0] = 1;
        else if(s[0] == 'O') num[i][0] = 2;
        else if(s[0] == 'X') num[i][0] = 3;
        int tmp = t[i], l = 0;
        while(tmp)
        {
            num[i][++l] = tmp % 2;
            tmp /= 2;
        }
    }
    for(int i = 31; i; --i)
    {
        int z = 0, o = 1;
        for(int j = 1; j <= n; ++j)
        {
            if(num[j][0] == 1) z &= num[j][i], o &= num[j][i];
            else if(num[j][0] == 2) z |= num[j][i], o |= num[j][i];
            else if(num[j][0] == 3) z = z xor num[j][i], o = o xor num[j][i];
        }
        if(o > z) ans[i] = 1;
        else ans[i] = 0;
    }
    for(int i = 31; i; --i)
        if(N + (ans[i] << (i-1)) <= m) N += (ans[i] << (i - 1));
    for(int i = 1; i <= n; ++i)
    {
        if(num[i][0] == 1) N &= t[i];
        else if(num[i][0] == 2) N |= t[i];
        else if(num[i][0] == 3) N ^= t[i];
    }
    printf("%d\n", N);
    return 0;
}


相关文章

  • BZOJ_3668_起床困难综合症

    About Problem The web : http://www.lydsy.com/JudgeOnline/...

  • 起床困难综合症

    毫无疑问,早上我又是寝室最后一个起床的。今天没有早八,十点才上课。我定的六点的闹钟,闹醒了室友,没闹醒我。 ...

  • 我的“起床困难综合症”

    “起床困难综合症”表现为晚上不想睡,早上不想起,有时一天没有精神。这种综合症从什么时候开始的,我也不记得了,好像是...

  • 起床困难

    今天连床都起不来了 难受的直哭 不知道是不是昨晚没吃药的原因 太折磨了

  • 起床困难

    文/明日之月 睡了三天懒觉后,今天早上闹钟响后,眼睛都睁不开了,太困了。这样的天气还有什么地方比被窝里舒服呢! 没...

  • 起床困难

    有没有按时起床,提前起床就那么困难吗?

  • 起床困难症

    我是资深的起床困难症,从小到大最大的爱好是睡懒觉。 上学时老师曾经说过,学习的选手分两种,百灵鸟型和猫头...

  • 困难的起床

    早起5点钟第七天。终于打卡一周了。 昨天晚上因为一些工作的事情,一直在处理,一晚上基本没做别的,睡得也有些晚了。我...

  • 破解起床困难

    最近收到很多家长有关于孩子早晨起床拖拉的问题,我想把自己的故事跟大家分享一下: 1.早晨唤醒孩子时,您自己的精神状...

  • 起床困难症

    一个寒假除了特殊情况我基本上没有早起过,每天睡到九十点还是不想起来,马上快要上班了不得不早起了,从上大学开始我就特...

网友评论

    本文标题:BZOJ_3668_起床困难综合症

    本文链接:https://www.haomeiwen.com/subject/djzokttx.html