题意 :就是有两个熊孩子要把一个正方形上的草都给烧掉,他俩同时放火烧,烧第一块的时候是不花时间的,每一块着火的都可以在下一秒烧向上下左右四块#代表草地,.代表着不能烧的。问你最少花多少时间可以烧掉,如果烧不掉就输出-1
思路 :这个题因为可以同时向上下左右同时烧过去,所以一看我就知道是BFS,但是知道没用啊,我做不出来啊,我一开始没想过来,以为两个人烧很麻烦,其实就是向普通的那样做,不过来个6重for循环就行了,其实就是看看有几个块,如果块的个数超过两个就为-1,两个的话,分别开始烧,哪个块里有最长路,就是烧的那个时间,不过你要枚举有最长路的那个的块的每一个可烧的点,从而找出时间最短的,1个块的时候也是一样的,求出最长路,枚举每个点的时候求最短时间。这个题看着芳姐的代码才理解。。。。。
不过做的时候没有去判断几个块,因为你BFS找的时候就处理了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h> #include <string.h> #include <iostream> #include <queue> const int INF = 99999999 ; int n,m ; char ch[15][15] ; int cnt ; int vis[110][110] ; int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}} ; struct node { int x,y ; int step ; }q1,q2 ,mapp[150]; using namespace std ; int BFS(int x1,int y1,int x2,int y2) { int maxx = 0 ; queue<node>que ; q1.x = x1,q1.y = y1,q1.step = 0 ; q2.x = x2,q2.y = y2,q2.step = 0 ; que.push(q1) ; que.push(q2) ; //memset(vis,0,sizeof(vis)) ; while(!que.empty()) { struct node st1, st = que.front() ; que.pop() ; for(int i = 0 ; i < 4 ; i++) { int xx = st.x+dir[i][0] ; int yy = st.y+dir[i][1] ; if(!vis[xx][yy] && ch[xx][yy] == '#' && (xx >= 0&&xx < n&&yy>=0&&yy<m)) { vis[xx][yy] = 1 ; st1.x = xx ,st1.y = yy ,st1.step = st.step+1 ; que.push(st1) ; } } maxx = max(maxx,st.step) ; } return maxx ; } int main() { int T ; scanf("%d",&T) ; for(int i = 1 ; i <= T ;i++) { scanf("%d %d",&n,&m) ; cnt = 0 ; for(int j = 0 ; j < n ; j++) { scanf("%s",ch[j]) ; for(int k = 0 ; k < m ; k++) if(ch[j][k] == '#') { cnt++ ; mapp[cnt].x = j ; mapp[cnt].y = k ; } } printf("Case %d: ",i) ; if(cnt <= 2 ) { printf("0 ") ; continue ; } int minn = INF ; for(int j = 0 ; j < cnt ; j++) { for(int k = j ; k < cnt ; k++) { memset(vis,0,sizeof(vis)) ; vis[mapp[j].x][mapp[j].y] = 1 ; vis[mapp[k].x][mapp[k].y] = 1 ; bool flag = false ; int minnn = BFS(mapp[j].x,mapp[j].y,mapp[k].x,mapp[k].y) ; for(int h = 0 ; h < n ; h++) { for(int l = 0 ; l < m ; l++) { if(ch[h][l] != '#') continue ; if(!vis[h][l]){flag = true ; break ;} } if(flag) break ; } if(!flag) minn = min(minn,minnn) ; } } if(minn == INF) printf("-1 ") ; else printf("%d ",minn) ; } return 0 ; }
这个是ZP的,写的差不多,不过用时100多ms,所以贴出来瞻仰一下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<math.h> #include<queue> using namespace std; #define LL __int64 int map[11][11]; int num[11][11][11][11]; int vis[11][11]; int n,m; struct list { int x; int y; int t; }p,q; queue<struct list >que; int xx[4]={1,-1,0,0}; int yy[4]={0,0,1,-1}; void dos(int i,int j,int a,int b,int t) { while(!que.empty())que.pop(); num[i][j][a][b]=0; p.x=a; p.y=b; p.t=0; que.push(p); vis[a][b]=1; while(!que.empty()) { p=que.front(); que.pop(); num[i][j][p.x][p.y]=p.t; for(int i=0;i<4;i++) { q.x=p.x+xx[i]; q.y=p.y+yy[i]; q.t=p.t+1; if(q.x<1||q.x>n||q.y<1||q.y>m)continue; if(vis[q.x][q.y])continue; if(map[q.x][q.y]==0)continue; que.push(q); vis[q.x][q.y]=1; } } } char str[111]; int main() { int T; int i,j,a,b,t,k; scanf("%d",&T); for(int _=1;_<=T;_++) { memset(map,0,sizeof(map)); scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { for(k=1;k<=n;k++) { for(t=1;t<=m;t++) { num[i][j][k][t]=999999; } } } } for(i=1;i<=n;i++) { scanf("%s",str); for(j=0;j<m;j++) { if(str[j]=='#') { map[i][j+1]=1; } } } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(map[i][j]==0)continue; memset(vis,0,sizeof(vis)); dos(i,j,i,j,0); } } //cout<<num[2][1][2][1]<<endl; //cout<<num[2][3][2][3]<<endl; int minn=999999; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(map[i][j]==0)continue; for(a=1;a<=n;a++) { for(b=1;b<=m;b++) { if(map[a][b]==0)continue; int tt=0; for(t=1;t<=n;t++) { for(k=1;k<=m;k++) { if(map[t][k]==0)continue; tt=max(tt,min(num[i][j][t][k],num[a][b][t][k])); } } minn=min(minn,tt); } } } } printf("Case %d: ",_); if(minn==999999) { cout<<-1<<endl; } else cout<<minn<<endl; } return 0; }
我还要贴一下会神的,因为限时1000ms,然后会神的代码就正好跑了1000ms。。。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<stdlib.h> #include<vector> #include<cmath> #include<queue> #include<set> using namespace std; #define N 110 #define LL long long #define INF 0xfffffff const double eps = 1e-8; const double pi = acos(-1.0); const double inf = ~0u>>2; char s[12][12]; struct node { int x,y; int num; }p[N]; int vis[12][12],dis[4][2] = {0,1,0,-1,-1,0,1,0},n,m; int judge(int x,int y) { if(x<1||x>n||y<1||y>m) return 0; if(vis[x][y]) return 0; if(s[x][y]!='#') return 0; return 1; } int bfs(int x1,int y1,int x2,int y2) { queue<node>q; node t1,t2; t1.num = 0;t1.x = x1,t1.y = y1; t2.num = 0;t2.x = x2,t2.y = y2; q.push(t1); q.push(t2); int mm=0; while(!q.empty()) { t1 = q.front();q.pop(); for(int i = 0 ; i < 4 ;i++) { int tx = t1.x+dis[i][0]; int ty = t1.y+dis[i][1]; if(judge(tx,ty)) { vis[tx][ty] = 1; t2.x = tx,t2.y = ty,t2.num = t1.num+1; q.push(t2); } }mm = max(mm,t1.num); } return mm; } int main() { int t,i,j,kk=0,g; cin>>t; while(t--) { g = 0; cin>>n>>m; for(i = 1; i <= n; i++) for(j = 1; j <= m ;j++) { cin>>s[i][j]; if(s[i][j]=='#') { g++; p[g].x = i; p[g].y = j; } } int minz = INF; for(i = 1; i <= g ; i++) for(j = i ;j <=g ;j++) { memset(vis,0,sizeof(vis)); vis[p[i].x][p[i].y] = 1; vis[p[j].x][p[j].y] = 1; int t1 = bfs(p[i].x,p[i].y,p[j].x,p[j].y); int flag = 0; for(int o = 1; o <= n;o++) { for(int e = 1; e <= m; e++) if(s[o][e]=='#') { if(!vis[o][e]) { flag = 1; break; } } if(flag) break; } if(!flag) { minz = min(minz,t1); } } printf("Case %d: ",++kk); if(minz!=INF) cout<<minz<<endl; else puts("-1"); } return 0; }