该题时限还是比较宽的,但是如果纯BFS还是会超时,所以要注意题目中的暗示 :任何一个2*2子网格中至少有一个障碍格 。 这表明障碍格有很多,那么重复搜索这些障碍格将会造成极大的浪费(因为我们开了三维数组记录三个鬼的状态,格子越多,状态也会以三次方的速度增加)。 所以我们可以将不是障碍的格子提出来再建一张图,用邻接表的方式。
那么怎么来建图呢? 受坐标离散化的启发,我们可以将每一个有用的格子映射成一个数字 ,作为它的标号 ,然后就可以方便的处理了 。
细节见代码:
#include<bits/stdc++.h> using namespace std; const int maxn = 260; int w,h,n,d[maxn][maxn][maxn],s[5],t[5],deg[maxn],g[maxn][maxn]; char a[20][20]; int dx[] = { 0,1,0,-1,0 }; int dy[] = { 1,0,-1,0,0 }; struct node{ int a,b,c; node(int a=0,int b=0,int c=0) : a(a),b(b),c(c) {} }; bool conflict(int a,int b,int a2,int b2) { return a2 == b2 || (a2 == b && a == b2); //两个鬼移动到同一个地方,或者移动到对方的地方 } int bfs() { queue<node> q; memset(d,-1,sizeof(d)); q.push(node(s[0],s[1],s[2])); d[s[0]][s[1]][s[2]] = 0; while(!q.empty()) { node u = q.front(); q.pop(); if(u.a == t[0] && u.b == t[1] && u.c == t[2]) return d[u.a][u.b][u.c]; for(int i=0;i<deg[u.a];i++) { int a2 = g[u.a][i]; for(int j=0;j<deg[u.b];j++) { int b2 = g[u.b][j]; if(conflict(u.a,u.b,a2,b2)) continue; for(int k=0;k<deg[u.c];k++) { int c2 = g[u.c][k]; if(conflict(u.a,u.c,a2,c2)) continue; if(conflict(u.b,u.c,b2,c2)) continue; if(d[a2][b2][c2] != -1) continue; d[a2][b2][c2] = d[u.a][u.b][u.c] + 1; q.push(node(a2,b2,c2)); } } } } return -1; } int main() { while(~scanf("%d%d%d",&w,&h,&n)) { if(!w && !h && !n) return 0; char c = getchar(); c = getchar(); for(int i=0;i<h;i++) gets(a[i]); int cnt = 0,x[maxn],y[maxn],id[20][20]; for(int i=0;i<h;i++) for(int j=0;j<w;j++) { if(a[i][j] != '#') { x[cnt] = i; y[cnt] = j; id[i][j] = cnt; if(islower(a[i][j])) s[a[i][j]-'a'] = cnt;//鬼的初始位置 else if(isupper(a[i][j])) t[a[i][j]-'A'] = cnt;//鬼的终止位置 ++cnt; } } for(int i=0;i<cnt;i++) { deg[i] = 0; for(int dir = 0; dir < 5; dir++) { int nx = dx[dir]+x[i] , ny = dy[dir]+y[i]; if(a[nx][ny] != '#') g[i][deg[i]++] = id[nx][ny]; } } if(n <= 2) { deg[cnt] = 1; g[cnt][0] = cnt; s[2] = t[2] = cnt++; } //将不存在的鬼映射成一个足够大的数,就不必再分情况讨论,减少代码量 if(n <= 1) { deg[cnt] = 1; g[cnt][0] = cnt; s[1] = t[1] = cnt++; } printf("%d\n",bfs()); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-08 06:07:36