hdu-4678-sg

Mine

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1731    Accepted Submission(s): 501


Problem Description
Have you ever played a game in Windows: Mine?
This game is played on a n*m board, just like the Pic(1)


On the board, Under some grids there are mines (represent by a red flag). There are numbers ‘A(i,j)’ on some grids means there’re A(i,j) mines on the 8 grids which shares a corner or a line with gird(i,j). Some grids are blank means there’re no mines on the 8 grids which shares a corner or a line with them.
At the beginning, all grids are back upward.
In each turn, Player should choose a back upward grid to click.
If he clicks a mine, Game over.
If he clicks a grid with a number on it , the grid turns over.
If he clicks a blank grid, the grid turns over, then check grids in its 8 directions.If the new grid is a blank gird or a grid with a number,it will be clicked too.
So If we click the grid with a red point in Pic(1), grids in the area be encompassed with green line will turn over.
Now Xiemao and Fanglaoshi invent a new mode of playing Mine. They have found out coordinates of all grids with mine in a game.  They also find that in a game there is no grid will turn over twice when click 2 different connected components.(In the Pic(2), grid at (1,1) will turn over twice when player clicks (0,0) and (2,2) , test data will not contain these cases).
Then, starting from Xiemao, they click the grid in turns. They both use the best strategy. Both of them will not click any grids with mine, and the one who have no grid to click is the loser.
Now give you the size of board N, M, number of mines K, and positions of every mine X i,Y i. Please output who will win.
 

 

Input
Multicase
The first line of the date is an integer T, which is the number of the text cases. (T<=50)
Then T cases follow, each case starts with 3 integers N, M, K indicates the size of the board and the number of mines.Then goes K lines, the ith line with 2 integer X i,Y i means the position of the ith mine.
1<=N,M<=1000 0<=K<=N*M 0<=X i<N 0<=Y i<M
 

 

Output
For each case, first you should print "Case #x: ", where x indicates the case number between 1 and T . Then output the winner of the game, either ”Xiemao” or “Fanglaoshi”. (without quotes)
 

 

Sample Input
2 3 3 0 3 3 1 1 1
 

 

Sample Output
Case #1: Xiemao Case #2: Fanglaoshi
 

 

Source
 
     给出一幅扫雷的地图,告诉你地雷所在位置,两个人轮流点击非炸弹且未显示出来的方格。点击的是空白格子的话会触发八联通格子的点击(如果他们未显示的话),点击的是数字格的话则只会显示点击的这一个格子,不再触发其他的操作。问先手是否处于胜态。
   可以将这个问题划分为一块块的小地图,所有联通的空白格和与他们相邻的数字格是一个独立的游戏,(除去他们之后单独的一个数字格也看作是一个独立的游戏),他们之间不会影响。只要计算出这些子问题的sg值就能推出胜态了。对于独立的一个数字格,sg=1。对于另一种情况,通过枚举可以发现,sg=(子地图中的数字格的数量)%2+1;
 
  一开始dfs一直mle,换成了bfs就好了。还有注意地图是[0][0]开始的,,c。
  
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <stdlib.h>
 6 #include <vector>
 7 #include <set>
 8 #include <queue>
 9 #include <stack>
10 using namespace std;
11 #define mp make_pair
12 #define pii pair<int,int>
13 int n,m,tot;
14 int e[1010][1010];
15 bool vis[1010][1010];
16 int fx[8][2]={-1,0,1,0,0,-1,0,1,-1,-1,-1,1,1,-1,1,1};
17 void bfs(int x,int y){
18     queue<pair<int,int> >q;
19     q.push(mp(x,y));
20     while(!q.empty()){
21         pii tmp=q.front();
22         q.pop();
23         if(vis[tmp.first][tmp.second]) continue;
24         vis[tmp.first][tmp.second]=1;
25         if(e[tmp.first][tmp.second]==2) {tot++;continue;}
26         for(int i=0;i<8;++i){
27             int dx=tmp.first+fx[i][0];
28             int dy=tmp.second+fx[i][1];
29             if(dx<1||dy<1||dx>n||dy>m||vis[dx][dy]) continue;
30             q.push(mp(dx,dy));
31         }
32     }
33 }
34 int main(){
35     int t,i,j,k,cas=0;
36     cin>>t;
37     while(t--){
38         memset(vis,0,sizeof(vis));
39         memset(e,0,sizeof(e));
40         cin>>n>>m>>k;
41         int x,y;
42         while(k--){
43             scanf("%d%d",&x,&y);
44             x++;
45             y++;
46             vis[x][y]=1;
47             e[x][y]=3;
48             for(i=0;i<8;++i){
49                 int dx=x+fx[i][0];
50                 int dy=y+fx[i][1];
51                 if(dx>0&&dy>0&&dx<=n&&dy<=m&&vis[dx][dy]==0) e[dx][dy]=2;
52             }
53         }
54         int sg=0;
55         for(i=1;i<=n;++i){
56             for(j=1;j<=m;++j){
57                 if(vis[i][j]||e[i][j]==2) continue;
58                     tot=0;
59                     bfs(i,j);
60                     sg^=(tot%2+1);
61             }
62         }
63         for(i=1;i<=n;++i)
64         for(j=1;j<=m;++j)
65         if(!vis[i][j]&&e[i][j]==2) sg^=1;
66         printf("Case #%d: ",++cas);
67         sg?puts("Xiemao"):puts("Fanglaoshi");
68     }
69     return 0;
70 }
View Code

 

  

转载于:https://www.cnblogs.com/zzqc/p/9335809.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值