[codeforces解题报告]More Reclamation

先贴上题目的链接http://codeforces.com/problemset/problem/335/C


这是今天凌晨的比赛的C题。 大半夜的,准备随便看看,理论ac下就撤回去睡觉的。 看到c,想了下,发现是SG博弈题目, 动态规划求解SG函数就好了。

然后觉得虽然好久没做过博弈的题目了,没想到这么轻松就想到了解法。不由得感慨一下自己当年的功底还没白费。于是准备a了这题就走。然后噼里啪啦敲完, 编译通过后,样例很轻松就过了。 然后pretest也一次性通过。然后就回去睡觉了。 结果第二天起来发现system test挂了- -

悲催的检查了下发现, 有两个bug,一个是有个边界写错了,另外一个错误是&的优先级比==低, 于是就囧了。 这pretest也太弱了!!

不多说了,直接上代码就好了。

#include<cstdio>
#include<algorithm>
#include<cassert>
#include<map>
#include<iostream>
#include<cstring>
#include<string>
#include<set>
#include<vector>
#include<cmath>
#include<iostream>
#include<fstream>
#include<sstream>
#include<queue>
using namespace std;

#define DBG false
#define out(x) cout << #x << ":  " << x << "   in line :   " << __LINE__ << endl;

typedef long long int64;

inline int Rint(){int x; scanf("%d", &x); return x;}

const int MAXN = 200;

int sg[4][4][MAXN];
int n, r;
pair<int ,int> data[MAXN];

int SG(int left, int right, int len){
    int& now = sg[left][right][len];
    if(now != -1)
        return now;
    if(len <= 0)
        return now = 0;
    if(len == 1){
        if(left == 0 || right == 0)
            return now = 1;
        if((left & right) != 0)
            return now = 1;
        else
            return now = 0;
    }
    now = 0;
    map<int ,int> hash;
    // left
    if(left == 0 || (left & (1 << 0)) != 0)
        hash[SG(1 << 0, right, len - 1)] = 1;
    if(left == 0 || (left & (1 << 1)) != 0)
        hash[SG(1 << 1, right, len - 1)] = 1;
    // right
    if(right == 0 || (right & (1 << 0)) != 0)
        hash[SG(left, 1 << 0, len - 1)] = 1;
    if(right == 0 || (right & (1 << 1)) != 0)
        hash[SG(left, 1 << 1, len - 1)] = 1;
    for(int i = 2; i < len; ++ i){
        for(int j = 0; j < 2; ++ j){
            int l1 = SG(left, 1 << j, i - 1);
            int l2 = SG(1 << j, right, len - i);
            hash[l1 ^ l2] = 1;
        }
    }
    map<int, int> :: iterator it;
    for(it = hash.begin(); it != hash.end(); ++ it){
        if(it->first != now)
            return now;
        now ++ ;
    }
    return now;
}
int work(){
    if(n == 0)
        return SG(0, 0, r);
    int ret = 0;
    if(data[0].first != 1)
        ret ^= SG(0, 1 << data[0].second, data[0].first - 1);
    if(data[n - 1].first != r)
        ret ^= SG(1 << data[n - 1].second, 0, r - data[n - 1].first);
    for(int i = 1; i < n; ++ i)
        ret ^= SG(1 << data[i - 1].second, 1 << data[i].second, data[i].first - data[i - 1].first - 1);
    return ret;
}
int main(){
    memset(sg, 0xff, sizeof(sg));
    while(2 == scanf("%d %d", &r, &n)){
        for(int i = 0; i < n; ++ i)
            data[i].first = Rint(), data[i].second = Rint() - 1;
        sort(data, data + n);
        if(work())
            printf("WIN\n");
        else
            printf("LOSE\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值