题目链接:Crosses and Crosses
分析:
对于每个位置i,可以分成两个子问题i-3和n-i-2.深搜一下就行了.
代码如下:
/*************************************************************************
> File Name: main.cpp
> Author:Eagles
> Mail:None
> Created Time: 2018年11月08日 星期四 18时54分28秒
> Description:poj3537
************************************************************************/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
#define N 2000
int sg[N];
int vis[N];
int dfs(int n)
{
if (n<=0)
return 0;
if (vis[n])
return sg[n];
int hash_val[N];
memset(hash_val,0,sizeof(hash_val));
for (int i=1; i<=n; i++)
{
int a,b;
if (!vis[i-3]&&i>=3)
dfs(i-3);
if (!vis[n-i-2]&&(n>=i+2))
dfs(n-i-2);
if (i<3)
a=0;
else
a=sg[i-3];
if (n<i+2)
b=0;
else
b=sg[n-i-2];
hash_val[a^b]=1;
//这样判断一下可以节省时间,如果直接hash_val[dfs(i-3)^dfs(n-i-2)]=1时间为3000MS,这样的时间是785MS
}
for (int i=0; i<N; i++)
{
if (hash_val[i] == 0)
{
vis[n]=true;
return sg[n]=i;
}
}
}
int main()
{
memset(vis,false,sizeof(vis));
memset(sg,0,sizeof(sg));
for (int i=3; i<=2000; i++)
{
if (!vis[i])
dfs(i);
}
int n;
while (~scanf("%d",&n))
{
printf("%d\n",sg[n]==0?2:1);
}
return 0;
}