题意:一个地图上有许多草堆,每次可以选择两个草堆点燃,这两个可以使一个,然后每秒它会烧到相邻的四个草堆,若是空地则不再燃烧
思路:我们可以将每个草堆点燃的所有时间处理出来,然后枚举任意两个求一下就行了
#include <queue>
#include <vector>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=20;
int n,m,ans,sum;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int vis[maxn][maxn],time[maxn][maxn][maxn][maxn];
char str[maxn][maxn];
struct point{
int x,y;
}sna[maxn*maxn];
struct edge{
int x,y,step;
};
void bfs(int x1,int y1){
queue<edge>que;
edge c,ne;
memset(vis,0,sizeof(vis));
c.x=x1,c.y=y1,c.step=0;
vis[c.x][c.y]=1;time[x1][y1][x1][y1]=0;
que.push(c);
while(!que.empty()){
c=que.front();que.pop();
for(int i=0;i<4;i++){
int xx=c.x+dir[i][0];
int yy=c.y+dir[i][1];
if(xx<0||xx>n-1||yy<0||yy>m-1||str[xx][yy]=='.'||vis[xx][yy]) continue;
time[x1][y1][xx][yy]=c.step+1;
ne.x=xx;ne.y=yy;ne.step=c.step+1;
vis[ne.x][ne.y]=1;
que.push(ne);
}
}
}
int main(){
int T,cas=1;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);sum=0;ans=inf;
memset(time,inf,sizeof(time));
for(int i=0;i<n;i++) scanf("%s",str[i]);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(str[i][j]=='#'){
sna[sum].x=i,sna[sum++].y=j;
bfs(i,j);
}
}
}
for(int i=0;i<sum;i++){
for(int j=i;j<sum;j++){
int fans=0,sum1=0;
int xx=sna[i].x,yy=sna[i].y,xxx=sna[j].x,yyy=sna[j].y;
for(int l=0;l<n;l++){
for(int p=0;p<m;p++){
if(str[l][p]=='#'&&(time[xx][yy][l][p]!=inf||time[xxx][yyy][l][p]!=inf)){
sum1++;fans=max(fans,min(time[xx][yy][l][p],time[xxx][yyy][l][p]));
}
}
}
if(sum1==sum) ans=min(ans,fans);
}
}
if(ans==inf) printf("Case %d: -1\n",cas++);
else printf("Case %d: %d\n",cas++,ans);
}
return 0;
}