HDU 4678 Mine

Mine

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


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 Xi,Yi. 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 Xi,Yi means the position of the ith mine.
1<=N,M<=1000 0<=K<=N*M 0<=Xi<N 0<=Yi<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
 

Recommend
zhuyuanchen520
 
题意: 给一个扫雷布局。 取空格, 会取掉一块。 或者取掉一个数字。 问谁赢

思路: 博弈

首先还原图形
然后广搜  每次搜出一个块。 
如果是偶数异或2, 基数异或1.
非0, 先发制人, 0, 后发制人。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;

//

const int V = 1000 + 50;
const int MaxN = 500 + 5;
const int mod = 1000000000 + 7;
const int inf = 1987654321;
int T, n, m, k, sum[V][V], ans, cu;
int d[8][2] = {-1, -1, -1, 0, -1, 1, 0, -1, 0, 1, 1, -1, 1, 0, 1, 1};
bool vis[V][V], visit[V][V];
int que[V * V], front, rear;
void bfs(int i, int j) {
    front = rear = 0;
    que[rear++] = i * m + j;
    visit[i][j] = true;
    cu++;
    while(front < rear) {
        int x = que[front] / m;
        int y = que[front] % m;
        front++;
        if(sum[x][y] != 0)
            continue;
        for(int q = 0; q < 8; ++q) {
            int xx = x + d[q][0], yy = y + d[q][1];
            if(xx < 0 || yy < 0 || xx >= n || yy >= m)
                continue;
            if(!vis[xx][yy] && !visit[xx][yy]) {
                que[rear++] = xx * m + yy;
                visit[xx][yy] = true;
                if(sum[xx][yy] > 0)
                    cu++;
            }
        }
    }
}
int main() {
    int i, j, c = 1;
    scanf("%d", &T);
    while(T--) {
        ans = 0;
        memset(sum, 0, sizeof(sum));
        memset(vis, false, sizeof(vis));
        memset(visit, false, sizeof(visit));
        scanf("%d%d%d", &n, &m, &k);
        while(k--) {
            int x, y;
            scanf("%d%d", &x, &y);
            vis[x][y] = true;
        }
        for(i = 0; i < n; ++i)
            for(j = 0; j < m; ++j) {
                int temp = 0;
                for(k = 0; k < 8; ++k) {
                    int xx = i + d[k][0], yy = j + d[k][1];
                    if(xx < 0 || yy < 0 || xx >= n || yy >= m)
                        continue;
                    temp += vis[xx][yy];
                }
                sum[i][j] = temp;
            }
        for(i = 0; i < n; ++i)
            for(j = 0; j < m; ++j)
                if(!vis[i][j] && sum[i][j] == 0 && !visit[i][j]) {
                    cu = 0; //统计每个块的个数。 整个空白为1, 数字为1.
                    bfs(i, j);
                    if(cu % 2 == 1)
                        ans ^= 1;
                    else
                        ans ^= 2;
                }
        for(i = 0; i < n; ++i)
            for(j = 0; j < m; ++j)
                if(!vis[i][j] && !visit[i][j])
                    ans ^= 1;
        printf("Case #%d: ", c++);
        if(ans != 0)
            printf("Xiemao\n");
        else
            printf("Fanglaoshi\n");
    }
}


没有更多推荐了,返回首页