点击打开链接
题意:一个地图上有许多草堆,每次可以选择两个草堆点燃,这两个可以使一个,然后每秒它会烧到相邻的四个草堆,若是空地则不再燃烧
思路:我们可以将每个草堆点燃的所有时间处理出来,然后枚举任意两个求一下就行了
#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; }