Find a way
Input
Output
For each test case output the minimum total time that both yifenfei and Merceki to arrival one of KFC.You may sure there is always have a KFC that can let them meet.
Sample Input
4 4 Y.#@ .... .#.. @..M 4 4 Y.#@ .... .#.. @#.M 5 5 Y..@. .#... .#... @..M. #...#
Sample Output
66 88 66
#include<stdio.h> #include<queue> #include<string.h> #define INF 0x3f3f3f3f /* * 0x3f3f3f3f的十进制是1061109567,是10^9级别的(和0x7fffffff一个数量级), * 而一般场合下的数据都是小于10^9的,所以它可以作为无穷大使用而不致出现数据大于无穷大的情形。 * 另一方面,由于一般的数据都不会大于10^9,所以当我们把无穷大加上一个数据时, * 它并不会溢出(这就满足了“无穷大加一个有穷的数依然是无穷大”), * 事实上0x3f3f3f3f+0x3f3f3f3f=2122219134,这非常大但却没有超过32-bit int的表示范围, * 所以0x3f3f3f3f还满足了我们“无穷大加无穷大还是无穷大”的需求。 */ #define max 201 /* * 如果用 const int max = 201,下面会报错 */ using namespace std; int n,m; char map[max][max]; int visit[max][max],time1[max][max],time2[max][max]; struct node { int x,y,step; }; void bfs(int startx,int starty,int p) { int move[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; node now,next; queue<node> q; //建立一个队列 q //将输入进来的(x,y)给点 now now.x=startx; now.y=starty; //因为输入为两个人的坐标,所以当前步数为零 now.step=0; visit[now.x][now.y]=1; //将该点设置为已访问 q.push(now);//压入队列 while(!q.empty()){ now=q.front(); q.pop(); if(map[now.x][now.y]=='@'){//找到一个KFC //记录两个坐标点到该坐标点的距离,放入time数组中 if(p==1){ time1[now.x][now.y]=now.step; }else{ time2[now.x][now.y]=now.step; } } /* * 思路: 上面取出点后,将该点四个方向进行遍历,如果可以走,则将其压入队列 并将该点的距离为上一个点的距离再加一, */ for(int k=0;k<4;k++) { next.x=now.x+move[k][0]; next.y=now.y+move[k][1]; if(!visit[next.x][next.y]&&next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&map[next.x][next.y]!='#') { next.step=now.step+1; visit[next.x][next.y]=1; q.push(next); } } } return; } int main(){ int min; //最小路径 int xx,yy,xm,ym; //两点坐标 while(scanf("%d%d",&n,&m)!=EOF){ for(int i=0;i<n;i++){ scanf("%s",&map[i]); //输入数据 for(int j=0;j<m;j++){ //找出两个坐标点 if(map[i][j]=='Y'){ xx=i; yy=j; } if(map[i][j]=='M'){ xm=i; ym=j; } } } //进行初始化 memset(visit,0,sizeof(visit)); memset(time1,INF,sizeof(time1)); bfs(xx,yy,1); memset(time2,INF,sizeof(time2)); memset(visit,0,sizeof(visit)); /* * 如果我们想要将某个数组清零,我们通常会使用memset(a,0,sizeof(a)),方便又高效, * 但是当我们想将某个数组全部赋值为无穷大时,就不能使用memset函数而得自己写循环了, * 因为memset是按字节操作的,它能够对数组清零是因为0的每个字节都是0(一般我们只有赋值 * 为-1和0的时候才使用它)。现 * 在好了,如果我们将无穷大设为0x3f3f3f3f,那么奇迹就发生了,0x3f3f3f3f的每个字节都是 * 0x3f! * 所以要把一段内存全部置为无穷大,我们只需要memset(a,0x3f,sizeof(a))。 */ bfs(xm,ym,2); min=INF; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(time1[i][j]!=INF&&time2[i][j]!=INF){ //比较选出到达KFC最短的路径和 int bri = time1[i][j]+time2[i][j]; if(bri<min) min = bri; } } } printf("%d\n",min*11); } return 0; }
文章来源: dfs/bfs--Find a way