您的位置:首页 > 其它

Codeforces 786A Berzerk(博弈)

2017-03-24 21:15 288 查看
题目链接

很明显的博弈题目,但是昨天打比赛的时候就是一直想不出来,一直在纠结这个loop的情况到底要怎么定义,感觉到深深的挫败感,自己之前专门看了一段时间博弈也没有任何用处= =太菜了

今天看了一下题解,发现思路其实还是很简单的,对于每个点都有两种状态,a推到这里和b推到这里,我们可以知道,对于1这个位置,无论哪个人在面临这样的局面时,都是必败态,我们从这个点出发,如果这个点是必败态(0),那么对于所有能一步走到这个点的位置,都有必胜态;对于每个状态,只有当它的后续状态都为1时,这个点为必败态,所以我们可以从1出发,对于每个能走到这个点的状态本身进行一个数量的统计,如果这个num=它的可操作步数,就说明这个点为必败态。

我们可以通过bfs来解决。

#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
#define ll long long
#define CL(a) memset(a,0,sizeof(a))
#define maxn 7010
#define mod 2520
int dp[2][maxn],num[2][maxn];
int n;
vector<int> v[2];

void bfs()
{
queue<pair<int,int> > que;
que.push(make_pair(0,0));
que.push(make_pair(1,0));
while(!que.empty())
{
int p=que.front().first;
int pos=que.fro
4000
nt().second;
int x=dp[p][pos];
que.pop();
if(x==0)
{
for(int i=0; i<v[!p].size(); i++)
{
int nxt=(pos-v[!p][i]+n)%n;
if(dp[!p][nxt]==-1)
{
dp[!p][nxt]=1;
que.push(make_pair(!p,nxt));
}
}
}
else
{
for(int i=0; i<v[!p].size(); i++)
{
int nxt=(pos-v[!p][i]+n)%n;
if(dp[!p][nxt]!=-1) continue;
if(num[!p][nxt]<v[!p].size()) num[!p][nxt]++;
if(num[!p][nxt]==v[!p].size())
{
dp[!p][nxt]=0;
que.push(make_pair(!p,nxt));
}
}

}
}

}

int main ()
{
memset(dp,-1,sizeof(dp));
memset(num,0,sizeof(num));
cin>>n;
for(int i=0; i<2; i++)
{
int k;
cin>>k;
for(int j=0; j<k; j++)
{
int m;
cin>>m;
v[i].push_back(m);
}
}
dp[0][0]=dp[1][0]=0;
bfs();
for(int i=0; i<2; i++)
{
for(int j=1; j<n; j++)
{
if(dp[i][j]==0) cout<<"Lose"<<' ';
else if(dp[i][j]==1) cout<<"Win"<<' ';
else cout<<"Loop"<<' ';
}
cout<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: