这道题就是说任选两个是‘#’的格子(‘#‘表示此格子是能够燃烧的草,‘.’ 表示是不能燃烧的石头),同时点燃,一个格子的火一秒钟能够将它上下左右的是草的格子都燃烧掉,问最少经过多少秒将所有是草的格子燃烧完,若不能燃烧完,输出-1。
解题思路很简单,就是分别枚举两个不相同的格子选中点燃(若只有一个或者两个格子,则直接输出0),枚举完所有情况后再比较输出所用最少的时间。代码如下:
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
char map[12][12];
int vis[12][12];
int d[4][2]={0,1,1,0,0,-1,-1,0}; //上下左右四个方向
int n,m;
struct node{
int x,y;
int step;
};
int fire[12][12]; //已经燃起火的格子为1
node f[100];
int cont; //是草的格子的数量
int Bfs(node s,node s1){
queue<node>q;
node e;
int i;
memset(fire,0,sizeof(fire));
fire[s.x][s.y]=1;
fire[s1.x][s1.y]=1;
q.push(s);
q.push(s1);
int num=2;
while(!q.empty())
{
s=q.front();
q.pop();
for(i=0;i<4;i++){
int xx=s.x+d[i][0];
int yy=s.y+d[i][1];
if(xx<0||yy<0||xx>=n||yy>=m)
continue;
if(map[xx][yy]=='.')continue;
if(fire[xx][yy])continue;
fire[xx][yy]=1;
num++;
e.x=xx;
e.y=yy;
e.step=s.step+1;
q.push(e);
}
if(q.empty()&&num==cont)return s.step; //所有为草的格子都被燃烧完了
}
return -1; //有为草的格子没有燃烧完
}
int main()
{
int T,i,j;
int cnt=0;
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
memset(f,0,sizeof(f));
for(i=0;i<n;i++){
scanf("%s",map[i]);
}
cont=0;
for(i=0;i<n;i++){ //任选两个是草的格子为起点开始Bfs
for(j=0;j<m;j++){
if(map[i][j]=='#'){
node a;
a.x=i;
a.y=j;
a.step=0;
f[cont++]=a;
}
}
}
if(cont==1||cont==2){ //有草的格子只有一个或者两个
printf("Case %d: 0\n",++cnt);
continue;
}
int ans=105;
for(i=0;i<cont;i++){ //找出所用时间最小的
for(j=i+1;j<cont;j++){
int ans1=Bfs(f[i],f[j]);
if(ans1==-1)
{
if(ans==105)ans=-1;
}
else{
if(ans==-1)ans=ans1;
else ans=(ans<ans1)?ans:ans1;
}
}
}
printf("Case %d: %d\n",++cnt,ans);
}
return 0;
}
本文介绍了一种在特定棋盘上进行的游戏,玩家需选择两个起始点点燃草地,并计算完全燃烧所需最短时间。文章提供了详细的算法实现过程及代码示例。
1989

被折叠的 条评论
为什么被折叠?



