Codeforces Round #406 (Div. 2):C. Berzerk(记忆化搜索解决博弈问题)

来源:互联网 发布:搜狗抢票软件 编辑:程序博客网 时间:2024/06/03 19:38

C. Berzerk
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Rick and Morty are playing their own version of Berzerk (which has nothing in common with the famous Berzerk game). This game needs a huge space, so they play it with a computer.

In this game there are n objects numbered from 1 to n arranged in a circle (in clockwise order). Object number 1 is a black hole and the others are planets. There's a monster in one of the planet. Rick and Morty don't know on which one yet, only that he's not initially in the black hole, but Unity will inform them before the game starts. But for now, they want to be prepared for every possible scenario.

Each one of them has a set of numbers between 1 and n - 1 (inclusive). Rick's set is s1 with k1 elements and Morty's is s2 with k2 elements. One of them goes first and the player changes alternatively. In each player's turn, he should choose an arbitrary number like x from his set and the monster will move to his x-th next object from its current position (clockwise). If after his move the monster gets to the black hole he wins.

Your task is that for each of monster's initial positions and who plays first determine if the starter wins, loses, or the game will stuck in an infinite loop. In case when player can lose or make game infinity, it more profitable to choose infinity game.

Input

The first line of input contains a single integer n (2 ≤ n ≤ 7000) — number of objects in game.

The second line contains integer k1 followed by k1 distinct integers s1, 1, s1, 2, ..., s1, k1 — Rick's set.

The third line contains integer k2 followed by k2 distinct integers s2, 1, s2, 2, ..., s2, k2 — Morty's set

1 ≤ ki ≤ n - 1 and 1 ≤ si, 1, si, 2, ..., si, ki ≤ n - 1 for 1 ≤ i ≤ 2.

Output

In the first line print n - 1 words separated by spaces where i-th word is "Win" (without quotations) if in the scenario that Rick plays first and monster is initially in object number i + 1 he wins, "Lose" if he loses and "Loop" if the game will never end.

Similarly, in the second line print n - 1 words separated by spaces where i-th word is "Win" (without quotations) if in the scenario that Morty plays first and monster is initially in object number i + 1 he wins, "Lose" if he loses and "Loop" if the game will never end.

Examples
input
52 3 23 1 2 3
output
Lose Win Win LoopLoop Win Win Win
input
84 6 2 3 42 3 6
output
Win Win Win Win Win Win WinLose Win Lose Lose Win Lose Lose


http://codeforces.com/contest/787/problem/C

问题概述:n-1个行星和一个黑洞排成一个圈(数字0表示黑洞,顺序:0→1→2→…→n-1→0),其中某个行星

上有一个怪兽,每个玩家有个长度为n的数字序列V1和V2,当前玩家可以将怪兽顺时针移动x个星球(x是当前玩家序

列中任意一个数),两个玩家轮流游戏,如果两个人都非常聪明,那么对于怪兽所在星球(1→n-1)的所有可能,第一

行输出第一名玩家先手的输赢情况(必赢是Win,必输是Lose,如果游戏会死循环就是Loop),第二行输出第二名

玩家先手的输赢情况(PS:经过黑洞也算一步)


题解:

(0表示第一个玩家,1表示第二个玩家)

记dp[x][y]为第x个玩家先手,怪兽当前在y号星球上的输赢状态,dp[x][y]==1表示必赢,dp[x][y]==-1表示必输,

dp[x][y]==2表示平局或还无法确定,v[x][y]==1表示dp[x][y]已经搜过(哪怕这个时候dp[x][y]还不能确定,也不能再

搜!不然会因为平局的可能出现死循环)

以下是所有能确定当前(x,y)输赢的情况:

①对于某个t∈V[x],(y+t)%(n-1)==0,则说明能一步获胜,dp[x][y]==1

(注意题目中第一行输入的n包括了黑洞,以总共只有n-1个行星)

②对于某个t∈V[x],dp[1-x][(y+t)%(n-1)]==-1,那么很显然dp[x][y]==1,因为你移动t步刚好是对方的必输态

③对于所有的t∈V[x],dp[1-x][(y+t)%(n-1)]==1,那么dp[x][y]==-1,因为你怎么移动都会移动到对方的必赢

态,那么你必输!


如果以上都不能确定,则dp[x][y]==2,即有可能平局或还不能确定,那么为什么不一定是平局?

因为每个状态只会搜过一次,假设b状态可以到达a和c两种状态,其中a状态可以决定状态b,而c状态会令程序

进入死循环(即a状态是必输态,那么b状态就可以确定必赢,可c状态会可能导致游戏平局或不确定),而不幸运的

是,c状态会被先搜到,而c状态又受b状态影响,这样c状态就会被标记,可是这个时候b状态还没确定呐,这样等b

状态确定了c状态已经不可能再被搜到了!这样原本必输或必赢的c就仍然不能确定,就很惨

那么如何解决问题?真的不确定或平局的多搜几次就好了,每次记得清空标记数组v(只要搜2次就能AC)


#include<stdio.h>#include<string.h>#include<vector>#include<algorithm>using namespace std;vector<int> V[2];int dp[2][7005], v[2][7005], n;int Sech(int x, int y){int i, t, sum, temp;if(dp[x][y]!=2)return dp[x][y];if(v[x][y])return dp[x][y];sum = 0;v[x][y] = 1;for(i=0;i<V[x].size();i++){t = (y+V[x][i])%(n+1);if(t==0){dp[x][y] = 1;return dp[x][y];}}for(i=0;i<V[x].size();i++){t = (y+V[x][i])%(n+1);temp = Sech(x^1, t);if(temp==-1){dp[x][y] = 1;return dp[x][y];}if(temp==1)sum += 1;}if(sum==V[x].size()){dp[x][y] = -1;return dp[x][y];}return dp[x][y];}int main(void){int i, m, x, j;for(i=0;i<=7000;i++)dp[0][i] = dp[1][i] = 2;scanf("%d%d", &n, &m);n -= 1;for(i=1;i<=m;i++){scanf("%d", &x);V[0].push_back(x);}scanf("%d", &m);for(i=1;i<=m;i++){scanf("%d", &x);V[1].push_back(x);}for(j=1;j<=2;j++){memset(v, 0, sizeof(v));for(i=n;i>=1;i--){Sech(0, i);Sech(1, i);}}for(i=0;i<=1;i++){for(j=1;j<=n;j++){if(dp[i][j]==1)printf("Win ");else if(dp[i][j]==-1)printf("Lose ");elseprintf("Loop ");}printf("\n");}return 0;}



1 0
原创粉丝点击