FZU2150 Fire Game

Stella981
• 阅读 402

题目:

两个熊孩子在n*m的平地上放火玩,#表示草,两个熊孩子分别选一个#格子点火,火可以向上向下向左向右在有草的格子蔓延,点火的地方时间为0,蔓延至下一格的时间依次加一。求烧完所有的草需要的最少时间。如不能烧完输出-1。

输入:

第一行,输入一个T,表示有T组测试数据。 每组数据由一个n,m分别表示行列

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

输出:

输出最少需要的时间>

样例:

FZU2150 Fire Game

分析:双起点的BFS,本质上就是枚举两个起点同时压入队列;

注意题目要求走过所有’#‘,所以BFS的循环不需要手动退出;  当’#‘个数<=2时需要特判

#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<numeric>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<cctype>
#define PI acos(-1.0)
const int INF = 0x3f3f3f3f;
const int NINF = -INF - 1;
typedef long long ll;
using namespace std;
int n, m;
int num;
char maze[12][12];
typedef pair<int, int> P;
P rec[105];//rec用于存储’#‘的数量及坐标位置
int d[12][12], used[12][12];
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int bfs(P x, P y)
{
    queue<P> q;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
            d[i][j] = INF;
    }
    memset(used, 0, sizeof(used));
    q.push(x), q.push(y);
    d[x.first][x.second] = 0, d[y.first][y.second] = 0;
    used[x.first][x.second] = 1, used[y.first][y.second] = 1;
    P temp;//用于存储队列front的pair定义在这是为了在队列被取尽后,循环外能得到最后一次循环的d值
    //cout << x.first << ',' << x.second << ' ' << y.first << ',' << y.second << endl;
    while (q.size())
    {
        temp = q.front();
        //cout << temp.first << ' ' << temp.second << endl;
        q.pop();
        for (int i = 0; i < 4; ++i)
        {
            int nx = temp.first + dx[i], ny = temp.second + dy[i];
            if (nx >= 0 && nx < n && ny >= 0 && ny < m && !used[nx][ny] && maze[nx][ny] != '.')
            {
                used[nx][ny] = 1;
                q.push(P(nx, ny));
                d[nx][ny] = d[temp.first][temp.second] + 1;
            }
        }
    }
    //cout << d[x.first][x.second] << ' ' << d[y.first][y.second] << endl;
    for (int i = 0; i < num; ++i)
    {
        if (d[rec[i].first][rec[i].second] == INF)//仍存在未烧到的’#‘
            return INF;
    }
    return d[temp.first][temp.second];
}
int main()
{
    int T, t = 0;
    cin >> T;
    while (T--)
    {
        t++;
        int ans = INF;
        cin >> n >> m;
        num = 0;
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < m; ++j)
            {
                cin >> maze[i][j];
                if (maze[i][j] == '#')
                    rec[num].first = i, rec[num++].second = j;
            }
        }
        if (num <= 1)//特判
        {
            cout << "Case " << t << ": " << 0 << endl;
            continue;
        }
        for (int i = 0; i < num; ++i)
        {
            for (int j = i + 1; j < num; ++j)
                ans = min(ans, bfs(rec[i], rec[j]));
        }
        if (ans != INF)
            cout << "Case " << t << ": " << ans << endl;
        else
            cout << "Case " << t << ": " << -1 << endl;
    }
    return 0;
}
点赞
收藏
评论区
推荐文章
DaLongggggg DaLongggggg
3年前
python刷题-字母图形
问题描述利用字母可以组成一些美丽的图形,下面给出了一个例子:ABCDEFGBABCDEFCBABCDEDCBABCDEDCBABC这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。输入格式输入一行,包含两个整数n和m,分别表示你要输出的图形的行数的列数。输出格式输出n行,每个m个字符,为你的图形。样例输入57样例输
先知 先知
3年前
C 语言代码大全
1两个数组的合并题目描述已知数组a中有m个按升序排列的元素,数组b中有n个按降序排列的元素,编程将a与b中的所有元素按降序存入数组c中。输入输入有两行,第一行首先是一个正整数m,然后是m个整数;第二行首先是一个正整数n,然后是n个整数,m,n均小于等于1000000。输出输出合并后的mn个整数,数据之间用空格隔开。输出占一行。样例输入4
DaLongggggg DaLongggggg
3年前
python-阶乘计算
问题描述  输入一个正整数n,输出n的值。  其中n123…n。算法描述  n可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个大整数a,A0表示a的个位,A1表示a的十位,依次类推。  将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。  首先将a设为1,然后乘2,
DaLongggggg DaLongggggg
3年前
python-算法训练 区间k大数查询
问题描述给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个。输入格式第一行包含一个数n,表示序列长度。第二行包含n个正整数,表示给定的序列。第三个包含一个正整数m,表示询问个数。接下来m行,每行三个数l,r,K,表示询问序列从左往右第l个数到第r个数中,从大往小第K大的数是哪个。序列元素从1开始标号。输出格式总共输出m行,每行一个数
DaLongggggg DaLongggggg
3年前
python刷题-进制转换
十六进制转八进制问题描述  给定n个十六进制正整数,输出它们对应的八进制数。输入格式  输入的第一行为一个正整数n(1<n<10)。  接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。输出格式  输出n行,每行为输入对应的八进制正整数。  【注意】  输入的十六进制数不会有
DaLongggggg DaLongggggg
3年前
python刷题-数列特征
问题描述给出n个数,找出这n个数的最大值,最小值,和。输入格式第一行为整数n,表示数的个数。第二行有n个数,为给定的n个数,每个数的绝对值都小于10000。输出格式输出三行,每行一个整数。第一行表示这些数中的最大值,第二行表示这些数中的最小值,第三行表示这些数的和。样例输入513245样例输出5211数据规模与约定1<n<10000。
Wesley13 Wesley13
2年前
Codevs 1159最大全0子矩阵
题目描述Description在一个0,1方阵中找出其中最大的全0子矩阵,所谓最大是指O的个数最多。输入描述InputDescription输入文件第一行为整数N,其中1<N<2000,为方阵的大小,紧接着N行每行均有N个0或1,相邻两数间严格用一个空格隔开。输出描述OutputDescription
Wesley13 Wesley13
2年前
1050 螺旋矩阵
1050 螺旋矩阵 (25分)本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第1个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;m≥n;且 m−n 取所有可能值中的最小值。输入格式:输入在第1行中给出一个正整数 N,第2行给出 N
Stella981 Stella981
2年前
Seeker的奇妙求职历险(网易互联网笔试)
素数的个数给出一个包含n个正整数的数组a,把a\i\拆分为若干个和为a\i\的素数,求拆分后最多能有多少个素数。第一行数据为n,表示数组长度,第二行为n个元素。输入3111输出01不可拆分输入135761为0个,3为1个,5为(2,3
Wesley13 Wesley13
2年前
2020 春招 华为笔试 2月26日
时间是两个小时,总共三道编程题目。第一道题目大意:  输入一个int类型的数,判断它的比特流中有多少个“010”,及第一个“101”的下标(这个下标是从低位向高位数的)。  如:输入:21      输出  20    原因:21 二进制表示为 00000000000000000000000000010101