HDU4678 Mine bfs+博弈 2013多校8

20 篇文章 0 订阅
11 篇文章 0 订阅

题目链接:HDU4678

Mine

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


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 imeans 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
 
题意:扫雷游戏,已知雷的数量和位置,每人一次要点击一个块,如果有数字就只能点开这一个块,如果没有数字,就可以点开所有空白格和其外层带数字的一圈。没格子可点的会输,问谁会赢。
题目分析:首先需要bfs,找出所有空白块以及周围相连带数字的块,以及单个带数字的块,联通的空白块算做一个。之后是博弈的过程,对于有空白块的堆,每次可以去一个或者全取出。可以简单打表sg函数,发现是1和2循环的。之后求所有堆的sg值异或和即可。

//
//  main.cpp
//  HDU4678
//
//  Created by teddywang on 2016/9/6.
//  Copyright © 2016年 teddywang. All rights reserved.
//

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int T,n,m,k,maze[1010][1010],ans;
int vis[1010][1010];
struct node {
    int x,y;
};

int check(int x,int y)
{
    if(x<0||y<0) return 0;
    if(x>=n||y>=m) return 0;
    if(maze[x][y]==-1) return 0;
    if(vis[x][y]==1) return 0;
    return 1;
}

void insert_lei(int x,int y)
{
    for(int i=x-1;i<=x+1;i++)
    {
        for(int j=y-1;j<=y+1;j++)
        {
            if(check(i,j)==0) continue;
            else maze[i][j]++;
        }
    }
}

void bfs(int x,int y)
{
    int num=0;
    if(check(x,y)==0) return ;
    vis[x][y]=1;
    queue<node> q;
    node buf,buf2;
    buf.x=x;buf.y=y;
    q.push(buf);
    while(!q.empty())
    {
        buf=q.front();
        q.pop();
        for(int i=buf.x-1;i<=buf.x+1;i++)
        {
            for(int j=buf.y-1;j<=buf.y+1;j++)
            {
                
                int bx=i;
                int by=j;
                if(check(bx,by)==0) continue;
                if(maze[bx][by]==0)
                {
                    buf2.x=bx;buf2.y=by;
                    q.push(buf2);
                    vis[bx][by]=1;
                }
                else if(maze[bx][by]>0)
                {
                    num++;
                    vis[bx][by]=1;
                }
            }
        }
    }
    ans^=num%2+1;
}

int main()
{
    cin>>T;
    int kase=1;
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&k);
        memset(maze,0,sizeof(maze));
        memset(vis,0,sizeof(vis));
        for(int i=0;i<k;i++)
        {
            int p1,p2;
            scanf("%d%d",&p1,&p2);
            maze[p1][p2]=-1;
            insert_lei(p1,p2);
        }
        ans=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(vis[i][j]==0&&maze[i][j]==0)bfs(i,j);
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(vis[i][j]==0&&maze[i][j]>0) ans^=1;
            }
        }
        printf("Case #%d: ",kase++);
        if(ans==0)
            printf("Fanglaoshi\n");
        else printf("Xiemao\n");
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值