Berzerk CodeForces - 787C (BFS)题解
Codeforces Round #406 (Div. 2)—— A - Berzerk
A. Berzerk 
 time limit per test4 seconds 
 memory limit per test256 megabytes 
 inputstandard input 
 outputstandard 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 
 5 
 2 3 2 
 3 1 2 3 
 output 
 Lose Win Win Loop 
 Loop Win Win Win 
 input 
 8 
 4 6 2 3 4 
 2 3 6 
 output 
 Win Win Win Win Win Win Win 
 Lose Win Lose Lose Win Lose Lose
這次CF的賽題的故事背景是我最愛的RICK AND MORTY,結(jié)果還是A不動題目,對不起他們= =。
題目大意:一個環(huán)形路徑編號為1-n,1號點為黑洞,玩家輪流讓怪物前進若干步(從自己的操作集合里隨便選),若該輪怪物走到黑洞,則該輪的玩家勝利。簡單來說,當怪物在x點時,輪到玩家a操作,他有個操作為前進y步,若前進y步之后剛好到達1號點,則怪物死亡,玩家a勝利。題目要求我們求出所以怪物初始位置和玩家ab各自先手的游戲結(jié)果。
設(shè)狀態(tài)dp[x][y]表示當前怪物在x點,輪到玩家y操作的游戲結(jié)果。所以dp[1][0]和dp[1][1]的結(jié)果都是失敗,若在dp[x][y]的情況下,玩家的任意操作到達的dp[x’][y’]的狀態(tài)是y’玩家失敗,則dp[x][y]為勝利(玩家選擇該操作即可勝利),反之,若玩家的所有選擇到達的下一個狀態(tài)dp[x’][y’]都是另一個玩家y’勝利,則dp[x][y]為失敗的,搜索就行。
不過因為會有陷入循環(huán)的loop的結(jié)果,所以遞推不大好實現(xiàn),我選擇了使用逆向bfs的方法,有點像拓撲排序(先初始化所有點的度數(shù)為可操作數(shù)),先讓點[0][0]和[0][1]入隊,對于任意當前隊列頭的點,如果這個點的狀態(tài)是失敗,則逆推出能從哪些點到這一點,那些點的狀態(tài)都是勝利并且入隊;如果這個點的狀態(tài)是失敗,則讓所有逆推出來的上一步的點的度數(shù)減一,如果該點的度數(shù)為0,則該點的狀態(tài)是失敗并且入隊。最后那些始終沒有入隊過的就是陷入循環(huán)的點了。
#include<iostream> #include<algorithm> #include<string.h> #include<stdio.h> #include<vector> #include<string> #include<cmath> #include<set> #include<queue> using namespace std; #define ll long long #define inf 0x3f3f3f3f const int mod = 1000000007; const int maxm = 50000005; const int maxn = 7005; const int M = 25; int n, m; int dp[maxn][2];//存結(jié)果 int sta[2][maxn];//存操作 int k[2]; bool vis[maxn][2];//存訪問 int deg[maxn][2];//存度數(shù) struct point{int p, turn, ans; }; queue<point> que; void bfs(){while (!que.empty()){point cnt=que.front(); que.pop();vis[cnt.p][cnt.turn] = 1;int turn = !cnt.turn;if (cnt.ans == 2){for (int i = 0; i < k[turn]; i++){int nex = (cnt.p + n - sta[turn][i])%n;if (!vis[nex][turn]){ dp[nex][turn] = 1; que.push({nex,turn,1}); }}}else{for (int i = 0; i < k[turn]; i++){int nex = (cnt.p + n - sta[turn][i]) % n;deg[nex][turn]--;if (deg[nex][turn] == 0&&!vis[nex][turn]){dp[nex][turn] = 2;que.push({ nex, turn, 2 });}}}} }int main() {scanf("%d", &n);scanf("%d", &k[0]);for (int i = 0; i < k[0]; i++){scanf("%d", &sta[0][i]);}scanf("%d", &k[1]);for (int i = 0; i < k[1]; i++){scanf("%d", &sta[1][i]);}for (int i = 0; i < n; i++){deg[i][0] = k[0];deg[i][1] = k[1];}dp[0][0] = dp[0][1] = 2;vis[0][0] = vis[0][1] = 1;que.push({ 0, 0 ,2});que.push({ 0, 1 ,2});bfs();for (int k = 0; k <= 1; k++){for (int i = 1; i < n; i++){if (!vis[i][k])printf("Loop ");else if (dp[i][k] == 1){ printf("Win "); }else printf("Lose ");}printf("\n");}return 0; }總結(jié)
以上是生活随笔為你收集整理的Berzerk CodeForces - 787C (BFS)题解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 怎么退出自适应巡航_20款奔驰GLE35
- 下一篇: 求助大佬,python类的问题
