先贴上题目的链接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;
}