FZU2150 Fire Game

题目:

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

输入:

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

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

输出:

输出最少需要的时间>

样例:

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

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

1#include<iostream> 2#include<sstream> 3#include<cstdio> 4#include<cstdlib> 5#include<string> 6#include<cstring> 7#include<algorithm> 8#include<functional> 9#include<iomanip> 10#include<numeric> 11#include<cmath> 12#include<queue> 13#include<vector> 14#include<set> 15#include<cctype> 16#define PI acos(-1.0) 17const int INF = 0x3f3f3f3f; 18const int NINF = -INF - 1; 19typedef long long ll; 20using namespace std; 21int n, m; 22int num; 23char maze[12][12]; 24typedef pair<int, int> P; 25P rec[105];//rec用于存储’#‘的数量及坐标位置 26int d[12][12], used[12][12]; 27int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 28int bfs(P x, P y) 29{ 30 queue<P> q; 31 for (int i = 0; i < n; ++i) 32 { 33 for (int j = 0; j < m; ++j) 34 d[i][j] = INF; 35 } 36 memset(used, 0, sizeof(used)); 37 q.push(x), q.push(y); 38 d[x.first][x.second] = 0, d[y.first][y.second] = 0; 39 used[x.first][x.second] = 1, used[y.first][y.second] = 1; 40 P temp;//用于存储队列front的pair定义在这是为了在队列被取尽后,循环外能得到最后一次循环的d值 41 //cout << x.first << ',' << x.second << ' ' << y.first << ',' << y.second << endl; 42 while (q.size()) 43 { 44 temp = q.front(); 45 //cout << temp.first << ' ' << temp.second << endl; 46 q.pop(); 47 for (int i = 0; i < 4; ++i) 48 { 49 int nx = temp.first + dx[i], ny = temp.second + dy[i]; 50 if (nx >= 0 && nx < n && ny >= 0 && ny < m && !used[nx][ny] && maze[nx][ny] != '.') 51 { 52 used[nx][ny] = 1; 53 q.push(P(nx, ny)); 54 d[nx][ny] = d[temp.first][temp.second] + 1; 55 } 56 } 57 } 58 //cout << d[x.first][x.second] << ' ' << d[y.first][y.second] << endl; 59 for (int i = 0; i < num; ++i) 60 { 61 if (d[rec[i].first][rec[i].second] == INF)//仍存在未烧到的’#‘ 62 return INF; 63 } 64 return d[temp.first][temp.second]; 65} 66int main() 67{ 68 int T, t = 0; 69 cin >> T; 70 while (T--) 71 { 72 t++; 73 int ans = INF; 74 cin >> n >> m; 75 num = 0; 76 for (int i = 0; i < n; ++i) 77 { 78 for (int j = 0; j < m; ++j) 79 { 80 cin >> maze[i][j]; 81 if (maze[i][j] == '#') 82 rec[num].first = i, rec[num++].second = j; 83 } 84 } 85 if (num <= 1)//特判 86 { 87 cout << "Case " << t << ": " << 0 << endl; 88 continue; 89 } 90 for (int i = 0; i < num; ++i) 91 { 92 for (int j = i + 1; j < num; ++j) 93 ans = min(ans, bfs(rec[i], rec[j])); 94 } 95 if (ans != INF) 96 cout << "Case " << t << ": " << ans << endl; 97 else 98 cout << "Case " << t << ": " << -1 << endl; 99 } 100 return 0; 101}
点赞
收藏

评论区

加载中...

相关推荐

python刷题-字母图形

问题描述利用字母可以组成一些美丽的图形,下面给出了一个例子:ABCDEFGBABCDEFCBABCDEDCBABCDEDCBABC这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。输入格式输入一行,包含两个整数n和m,分别表示你要输出的图形的行数的列数。输出格式输出n行,每个m个字符,为你的图形。样例输入57样例输

C 语言代码大全

1两个数组的合并题目描述已知数组a中有m个按升序排列的元素,数组b中有n个按降序排列的元素,编程将a与b中的所有元素按降序存入数组c中。输入输入有两行,第一行首先是一个正整数m,然后是m个整数;第二行首先是一个正整数n,然后是n个整数,m,n均小于等于1000000。输出输出合并后的mn个整数,数据之间用空格隔开。输出占一行。样例输入4

python-阶乘计算

问题描述  输入一个正整数n,输出n的值。  其中n123…n。算法描述  n可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个大整数a,A0表示a的个位,A1表示a的十位,依次类推。  将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。  首先将a设为1,然后乘2,

python-算法训练 区间k大数查询

问题描述给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个。输入格式第一行包含一个数n,表示序列长度。第二行包含n个正整数,表示给定的序列。第三个包含一个正整数m,表示询问个数。接下来m行,每行三个数l,r,K,表示询问序列从左往右第l个数到第r个数中,从大往小第K大的数是哪个。序列元素从1开始标号。输出格式总共输出m行,每行一个数

python刷题-进制转换

十六进制转八进制问题描述  给定n个十六进制正整数,输出它们对应的八进制数。输入格式  输入的第一行为一个正整数n(1<n<10)。  接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。输出格式  输出n行,每行为输入对应的八进制正整数。  【注意】  输入的十六进制数不会有

python刷题-数列特征

问题描述给出n个数,找出这n个数的最大值,最小值,和。输入格式第一行为整数n,表示数的个数。第二行有n个数,为给定的n个数,每个数的绝对值都小于10000。输出格式输出三行,每行一个整数。第一行表示这些数中的最大值,第二行表示这些数中的最小值,第三行表示这些数的和。样例输入513245样例输出5211数据规模与约定1<n<10000。