【题目大意】:给出一个n*m的矩阵,两个人轮流切割...直到一方不能切割为止,问先手的胜负情况
【解题思路】:原本看完题目觉得很简单,直接裸敲了个dfs~~结果无情的TLE...然后想想看看sg函数,然后发现貌似自己有点明白了。
这道题的关键在于把问题转化为nim博弈...换句话话说一切博弈皆nim...
设(n,k)为当前状态...则其后继状态可以为很多种,而我们将其均视为(n,k)的后继状态时,我们可以得到sg(n,k)=sg(a)^sg(b)....;(a,b设为其后继状态)...
因此...转化为nim博弈问题...
【代码】:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <cctype>
#include <map>
#include <iomanip>
using namespace std;
#define eps 1e-8
#define pi acos(-1.0)
#define inf 1<<30
#define linf 1LL<<60
#define pb push_back
#define lc(x) (x << 1)
#define rc(x) (x << 1 | 1)
#define lowbit(x) (x & (-x))
#define ll long long
ll dp[220][220];
ll dfs(int n,int k){
int vis[220];
int x,y;
if (dp[n][k]!=-1) return dp[n][k];
memset(vis,0,sizeof(vis));
for (int i=2; i<=k-2; i++){
y=dfs(n,i)^dfs(n,k-i);
vis[y]=1;
}
for (int i=2; i<=n-2; i++){
x=dfs(i,k)^dfs(n-i,k);
vis[x]=1;
}
int cnt=0;
while (vis[cnt]) cnt++;
dp[n][k]=cnt;
return cnt;
}
int n,k;
int main() {
memset(dp,-1,sizeof(dp));
dp[2][2]=0;
dp[2][3]=0;
dp[3][2]=0;
while (~scanf("%d%d",&n,&k)){
ll tmp=dfs(n,k);
if (tmp<=0) cout << "LOSE" << endl;
else cout << "WIN" << endl;
}
return 0;
}