Fire Game(BFS)

Description

Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns). At the beginning, each grid of this board is consisting of grass or just empty and then they start to fire all the grass. Firstly they choose two grids
which are consisting of grass and set fire. As we all know, the fire can spread among the grass. If the grid (x, y) is firing at time t, the grid which is adjacent to this grid will fire at time t+1 which refers to the grid (x+1, y), (x-1, y), (x, y+1), (x,
y-1). This process ends when no new grid get fire. If then all the grid which are consisting of grass is get fired, Fat brother and Maze will stand in the middle of the grid and playing a MORE special (hentai) game. (Maybe it’s the OOXX game which decrypted
in the last problem, who knows.)

You can assume that the grass in the board would never burn out and the empty grid would never get fire.

Note that the two grids they choose can be the same.

Input

The first line of the date is an integer T, which is the number of the text cases.

Then T cases follow, each case contains two integers N and M indicate the size of the board. Then goes N line, each line with M character shows the board. “#” Indicates the grass. You can assume that there is at least one grid which is consisting of grass
in the board.

1 <= T <=100, 1 <= n <=10, 1 <= m <=10

Output

For each case, output the case number first, if they can play the MORE special (hentai) game (fire all the grass), output the minimal time they need to wait after they set fire, otherwise just output -1. See the sample input and output for more details.

Sample Input

4
3 3
.#.
###
.#.
3 3
.#.
#.#
.#.
3 3
...
#.#
...
3 3
###
..#
#.#

Sample Output

Case 1: 1
Case 2: -1
Case 3: 0
Case 4: 2

解题思路:

W代表草坪,只有草坪才能燃烧,让你给两块草坪点火,火势只能向上下左右蔓延,问把所有草坪烧完的最短时间。求最短时间又得把对整个图进行检索,典型的BFS,火向四周蔓延一次,时间加一。该题特别之处就在于是两处同时进行BFS。其实完全可以看做交替进行BFS,即你先放火,我再放火,你的火先蔓延一块草地,我再跟着蔓延一块草地,直到烧完。所以检索的时候,当第一把火燃烧到第二把火蔓延的地方会发现,悲剧了,那里的草已经被烧完了。。。。这样间接保证了时间上的同步。

AC代码:

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
const int maxn = 20, INF = 999999999;
using namespace std;
bool visited[maxn][maxn];
int pos, n, m, dir[4][2] = {{0,1},{1,0},{-1,0},{0,-1}};  // 定义一个二维数组代表四个方向
char map[maxn][maxn];
struct node
{
    int x, y;
}p[maxn * maxn];   // 用结构体记录草坪的坐标
queue<node> point;
int min(int a,int b)
{
    return a < b ? a : b;
}
bool Flag(int x,int y)  // 判断该坐标是否是草坪并有无被烧过
{
    if(x >= 0 && x < n && y >= 0 && y < m && map[x][y] == '#' && visited[x][y] == 0)
        return true;
    return false;
}
int Bfs()
{
    int time = 0;
    while(!point.empty())
    {

        int m =point.size();
        while(m--)
        {
            node now = point.front();
            point.pop();
            for(int j = 0; j < 4; j++)
            {
                int temp_x = now.x + dir[j][0];
                int temp_y = now.y + dir[j][1];
                if(Flag(temp_x,temp_y))
                {
                    node temp;
                    temp.x = temp_x;
                    temp.y = temp_y;
                    visited[temp.x][temp.y] = 1;
                    point.push(temp);
                    pos--;
                }
            }
        }
        time++;
    }
    if(pos == 0)  // 判断草坪是否烧完,烧完即为0
        return time - 1;
    else
        return INF;
}
int main()
{
    int t, ans, count = 0;
    scanf("%d", &t);
    while(t--)
    {
        memset(visited, 0, sizeof(visited));
        int k = 0;
        ans = INF;
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; i++)
        {
            scanf("%s", map[i]);
            for(int j = 0; j < m; j++)
            {
                if(map[i][j] == '#')  // 判断该坐标是否是草坪
                {
                    p[k].x = i;
                    p[k].y = j;
                    k++;
                }
            }
        }
        for(int i = 0; i < k - 1; i++)      // 遍历所有可能的两处放火地点
            for(int j = i + 1; j < k; j++)
            {
                memset(visited, 0, sizeof(visited));
                point.push(p[i]);
                point.push(p[j]);
                visited[p[i].x][p[i].y] = 1;
                visited[p[j].x][p[j].y] = 1;     // 放火的两处标记已访问
                pos = k - 2;   // pos记录了还需要烧的草坪,减去了两处放火的草坪
                int t = Bfs();
                ans = min(ans,t); // 找出最小的燃烧时间
            }
        if(k == 1)  // 不要漏了整块地图只有一块草坪的情况,这时候只能在同一地点放火,时间为0
            printf("Case %d: 0\n", ++count);
        else if(ans == INF)
            printf("Case %d: -1\n", ++count);
        else
            printf("Case %d: %d\n", ++count, ans);
    }
    return 0;
}
时间: 2024-10-10 22:30:36

Fire Game(BFS)的相关文章

(简单) UVA 11624 Fire! ,BFS。

Description Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the maze neglected to create a fire escape plan. Help Joe escape the maze. Given Joe's location in the maze and which squares of the maze are o

(FZU 2150) Fire Game (bfs)

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2150 Problem Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns). At the beginning, each grid of this board is consisting of grass or just empty a

UVA11624 Fire! BFS

11624 Fire!Joe works in a maze. Unfortunately, portions of the maze have caughton fire, and the owner of the maze neglected to create a fire escape plan.Help Joe escape the maze.Given Joe’s location in the maze and which squares of the maze areon fir

UVALive 5066 Fire Drill BFS+背包

H - Fire Drill Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 5066 Description Joko is taking part in a fire drill which is held by the Jakarta Fire Department to recruit new firemen. The drill i

UVA - 11624 - Fire! (BFS的应用)

A - Fire! Time Limit:1000MS    Memory Limit:0KB    64bit IO Format:%lld & %llu SubmitStatus Description Problem B: Fire! Joe works in a maze. Unfortunately, portions of the maze have caught on fire,and the owner of the maze neglected to create a fire

Fire! 双向BFS追击问题

Fire! Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the maze neglected to create a fire escape plan. Help Joe escape the maze. Given Joe’s location in the maze and which squares of the maze are on fire

UVA 11624 - Fire!(BFS)

UVA 11624 - Fire! 题目链接 题意:一个迷宫,一些格子着火了,火每秒向周围蔓延,现在J在一个位置,问他能走出迷宫的最小距离 思路:BFS2次,第一次预处理每个位置着火时间,第二次根据这个再BFS一次 代码: #include <cstdio> #include <cstring> #include <queue> using namespace std; const int d[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; co

UVALive 5066 Fire Drill --BFS+DP

题意:有一个三维的地图,有n个人被困住,现在消防队员只能从1楼的一个入口进入,营救被困者,每一个被困者有一个价值,当消防队员找到一个被困者之后,他可以营救或者见死不救,如果救的话,他必须马上将其背到入口处,不得停下,不得同时救多个人,而且回去的时间一步要做两步走,即时间增加一倍.求在给定时间S内,能救到的人的最大价值总和. 解法:bfs一遍记录每个点离起点的最短距离,那么救这个人的花费就是3*dis,然后已经知道救这个人的价值,那么最后求一个01背包即可. 要注意一个人都救不到的地方,我开始将d

FZU2150 Fire Game BFS搜索

题意:就是选两个点出发,只能走草坪,看能不能走完所有的草坪 分析:由于数据范围很小,所有枚举这两个点,事先将所有的草坪点存起来,然后任选两个点走,(两个点可以是同一个点) 然后BFS就行了 注:无解的情况很好做,事先深搜判连通块的个数就好,大于2就无解(代码比较烂) #include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<cmath> #