RQNOJ 83 魔兽世界
从左上角到右下角,问最少几步能到。
有传送门:大写字母之间可以互相传送。
坑点是,有一个点从一个跳到另一个,那么不能标记进入的门。
也就是说只要标记道德那个地方就行了。
#include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <iostream> #include <vector> #include <cmath> #include <map> #include <string> #include <stack> #include <queue> using namespace std; int dd[4][2]= {{1,0},{-1,0},{0,1},{0,-1}}; char str[5]; struct Point { int x,y,step; }; char mp[110][110]; int go[110][110]; int gate[30][4]; int ncas=0; queue<Point>q; int main() { int n,m; while (scanf ("%d%d",&n,&m)!=EOF) { while (!q.empty()) q.pop(); memset(mp,0,sizeof(mp)); memset(go,0,sizeof(go)); memset(gate,-1,sizeof(gate)); for (int i=0; i<n; i++) { scanf ("%s",mp[i]); } for (int i=0;i<n;i++) { for (int j=0;j<m;j++) { if (mp[i][j]>='A'&&mp[i][j]<='Z') { if (gate[mp[i][j]-'A'][0]==-1) { gate[mp[i][j]-'A'][0]=i; gate[mp[i][j]-'A'][1]=j; } else { gate[mp[i][j]-'A'][2]=i; gate[mp[i][j]-'A'][3]=j; } } } } Point s; s.x=0; s.y=0; s.step=1; go[s.x][s.y]=1; q.push(s); int flag=0; while (!q.empty()) { Point tmp=q.front(); q.pop(); // printf ("%d %d---%d\n",tmp.x,tmp.y,tmp.step); if (tmp.x==n-1&&tmp.y==m-1) { flag=tmp.step; break; } for (int i=0; i<4; i++) { int tx=tmp.x+dd[i][0]; int ty=tmp.y+dd[i][1]; Point hh; hh.x=tx; hh.y=ty; hh.step=tmp.step+1; if (tx>=n||ty>=m||tx<0||ty<0||mp[tx][ty]=='1') continue; if (mp[tx][ty]>='A'&&mp[tx][ty]<='Z') { if (tx==gate[mp[tx][ty]-'A'][0]&&ty==gate[mp[tx][ty]-'A'][1]) hh.x=gate[mp[tx][ty]-'A'][2], hh.y=gate[mp[tx][ty]-'A'][3]; else hh.x=gate[mp[tx][ty]-'A'][0], hh.y=gate[mp[tx][ty]-'A'][1]; } if (go[hh.x][hh.y]) continue; go[hh.x][hh.y]=hh.step; q.push(hh); } } if (flag==0) printf ("No Solution.\n"); else printf ("%d\n",flag-1); } return 0; }