66
这道题就是队列加BFS,我用的方法就是两个人都搜索一遍,
KFC数组初始化为-1,第一个人走到任何一个KFC,将步数加过去,
第二个人走到相应的也把步数加过去,
这样最后找最小的就可以了。
为什么用-1呢,因为如果输入下图:
//Find a way #include <iostream> #include <string.h> #include <queue> using namespace std; int map[1001][1001]; bool vis[1001][1001]; int KFC[50001]; int dis[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; int m,n,num; // 坐标结构体 struct Coordinate { int x,y,step; }; // 判断是否界外或者撞墙或者已经走过 bool isforbid(int x,int y) { if(x<0 || y<0 || x>=m || y>=n) return 1; if(map[x][y]==-1 || vis[x][y]==1) return 1; return 0; } void bfs(int x,int y) { // 初始化 memset(vis,0,sizeof(vis)); queue <Coordinate> q; Coordinate ft,next; int i; // 先压入一个值,避免空队列 ft.x=x,ft.y=y,ft.step=0; vis[x][y]=1; q.push(ft); while(!q.empty()) { ft=q.front(); q.pop(); // 如果搜索到任何一个KFC,都记录下来,并继续执行 if(map[ft.x][ft.y]>0) KFC[map[ft.x][ft.y]]+=ft.step; for(i=0;i<4;++i) { next.x=ft.x+dis[i][0]; next.y=ft.y+dis[i][1]; if(isforbid(next.x,next.y)) continue; next.step=ft.step+1; vis[next.x][next.y]=1; q.push(next); } } } int main() { char c; int i,j,min; int yx,yy,mx,my; while(cin>>m>>n) { memset(KFC,-1,sizeof(KFC)); num=1; // 输入时寻找Y点,M点坐标,并且将每一个KFC用1,2,3,4等字符代替 for(i=0;i<m;++i) for(j=0;j<n;++j) { cin>>c; if(c=='Y') {yx=i;yy=j;map[i][j]=0;} else if(c=='M') {mx=i;my=j;map[i][j]=0;} else if(c=='@') map[i][j]=num++; else if(c=='#') map[i][j]=-1; else map[i][j]=0; } bfs(yx,yy); bfs(mx,my); // 遍历每个KFC中两人到达距离和,找最小 min=999999999; for(i=1;i<num;++i) { if(KFC[i]==-1) continue; min=(min>KFC[i]+1)?KFC[i]+1:min; } cout<<min*11<<endl; } return 0; }