csu1259
来源:互联网 发布:js 修改样式 编辑:程序博客网 时间:2024/05/02 05:45
Description
一个每块地板标记着0~9某个数字的迷宫,其中标记1的地板不可以走,标记2~9的地板可以不花时间地跳到任意相同数字的位置,也可以和标记0的地板一样向前后左右任意方向花1个单位时间移动1的距离。给出起点和终点,求起点到终点的最短时间。
Input
每组数据第一行一个n,表示尺寸,2 <= n <= 100。
接下来n行每行n个0~9的字符,或S表示起点,E表示终点,S和E的运动规则与0相同。整个地图只有一个S和一个E。
Output
每组数据输出一个数,占一行,表示起点到终点可以花费的最短时间。
如果无法到达重点,输出"Oh No!"
Sample Input
50S100001310030000000003E03S1201010E
Sample Output
4Oh No!
题目解决方法一看就是用bfs。需要用到两个队列,一个用来存储每个数字的所有位置,另一个进行搜索
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#define N 110using namespace std;typedef struct Node{ int x,y,step;}Ac;int visit[N][N],map[N][N];int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};int n,sx,sy,ex,ey;queue<Ac> Q[10];//用来存放2~9所有节点的位置struct cmp{ bool operator () (const Ac n1,const Ac n2) const { return n1.step>n2.step; }};bool check(int x,int y){ if(x<0||x>=n||y<0||y>=n||map[x][y]==1||visit[x][y]==1){ return false; } return true;}int bfs(){ Ac p,q; priority_queue<Ac,vector<Ac>,cmp> pq; p.step=0,p.x=sx,p.y=sy; visit[sx][sy]=1; pq.push(p); while(!pq.empty()) { p=pq.top(); pq.pop(); if(p.x==ex&&p.y==ey){//找到目标了 return p.step; } for(int i=0;i<4;i++){ q=p; q.x+=dx[i]; q.y+=dy[i]; if(check(q.x,q.y)){//符合判断条件 visit[q.x][q.y]=1;//标记已经访问 if(map[q.x][q.y]==0){//如果为0,直接步数加1,加入队列 q.step++; pq.push(q); } else{//如果是2~9之间的数 Ac temp; while(!Q[map[q.x][q.y]].empty())//这个数所对应的位置不止一个,就是还有其他位置可以跳 { temp=Q[map[q.x][q.y]].front(); Q[map[q.x][q.y]].pop(); visit[temp.x][temp.y]=1; temp.step=q.step+1; pq.push(temp);//将这些全部入队,表示可以跳的temp所对应的位置 } } } } } return -1;}int main(){ while(~scanf("%d",&n)) { char c; memset(visit,0,sizeof(visit)); memset(map,0,sizeof(map)); getchar(); for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ cin>>c; if(c=='S'){ sx=i; sy=j; map[i][j]=0; } else if(c=='E'){ ex=i; ey=j; map[i][j]=0; } else{ map[i][j]=c-'0'; if(map[i][j]>=2&&map[i][j]<=9){ Ac temp; temp.x=i,temp.y=j; Q[map[i][j]].push(temp); } } } getchar(); } int ans=bfs(); if(ans==-1){ printf("Oh No!\n"); } else printf("%d\n",ans); } return 0;}
0 0