3 5 6 3 XXD... ....E. ....X. ....S. ...... 5 6 3 XDX... ....E. ...... ....S. ...... 5 6 8 XXDX.. .XEX.. ...... ....S. ......
Case 1: -1 Case 2: 3 Case 3: -1
代码:
#include<cstdio> #include<cstring> #include<queue> #include<iostream> using namespace std; const int maxn = 105; struct zc { int x,y,s,t; }p,q,tmp; int vis[maxn][maxn][4];//设大明1小明2,如果为3是都找到了 char map[maxn][maxn]; int n,m,t,sx,sy; int fx[4][2]={0,1,1,0,0,-1,-1,0}; int cal(int x,int y)//计算这个点能看到的大明二明 { int res = 0,nx,ny; for(int i=0;i<4;i++) { nx = x + fx[i][0]; ny = y + fx[i][1]; while(nx <= n && nx >= 1 && ny <= m && ny >= 1 && map[nx][ny]=='.') { nx=nx+fx[i][0]; ny=ny+fx[i][1]; } if(nx <= n && nx >= 1 && ny <= m && ny >= 1) { if(map[nx][ny]=='D') res+=1; else if(map[nx][ny]=='E') res+=2; } } return res; } int bfs() { memset(vis,0,sizeof(vis)); queue<zc>Q; p.x = sx; p.y = sy; p.s = cal(sx,sy); p.t = 0; Q.push(p); vis[p.x][p.y][p.s] = 1; while(!Q.empty()) { q=Q.front();Q.pop(); if(q.s==3) return q.t; int nx,ny,ns; for(int i=0;i<4;i++) { nx = q.x + fx[i][1]; ny = q.y + fx[i][0]; int ttt=cal(nx,ny); if(q.s!=ttt){//1!2时 ns=q.s+ttt; } else ns=q.s;//等于就算了 if(ns > 3) ns = 3; if(nx < 1 || nx > n || ny < 1 || ny > m || map[nx][ny] != '.' || vis[nx][ny][ns]) continue; tmp.x = nx; tmp.y = ny; tmp.s = ns; tmp.t = q.t + 1; if(tmp.t > t) continue; vis[nx][ny][ns] = 1; Q.push(tmp); } } return -1; } int main() { int cas; scanf("%d",&cas); for(int T = 1 ; T <= cas; T++) { scanf("%d%d%d",&n,&m,&t); for(int i=1;i<=n;i++) { scanf("%s",map[i]+1); for(int j=1;j<=m;j++) { if(map[i][j]=='S') { sx=i;sy=j; } } } printf("Case %d:\n%d\n",T,bfs()); } return 0; }