小S练跑步 / run
【问题描述】
小S是一个爱锻炼的孩子,他在放假期间坚持在A公园练习跑步。
但不久后,他就开始为在重复的地点练习感到厌烦了,他就打算去B公园跑步。
但是小S由于没有去过B公园,他不知道B公园是否适合练习跑步,又不知道在B公园怎样跑是最优的。所以小S就去B公园进行了一番勘测。
小S在进行了一番勘测后,画出了一张地图,地图每一个位置上都辨识了小S到达该位置后不能往哪一个方位移动。其中有5种表示的符号:“U”代表不能向上移动,“D”代表不能向下移动,“L”代表不能向左移动,“R”代表不能向右移动,如果该位置有障碍物,小S到达那里后无法继续训练,就用“S”来代表。整个公园共有n行m列,小S会从第1行第1列出发,到第n行第m列结束他的练习。
现在小S想要知道,从起点(即第1行第1列)到终点(第n行第m列),途中最少要改变几次方向(即上一次移动的方向和这一次移动的方向不一样)?
注意:小S如在训练途中离开公园(即地图范围),则算是结束训练。
【输入】
第1行两个整数n和m,它们的定义请看【题目描述】。
第2~n+1行,每行有m个字符,表示小S的移动方向。
【输出】
如果小S从第1行第1列出发无论如何都到达不了第n行第m列,输出“No Solution”,否则输出小S途中最少要改变方向的次数。
【输入输出样例】
3 3 ULL LDU SUD |
1
|
【样例解释】
小S先向右移动移动了2格,再向下移动2格,就到达了终点,这样只用改变一次方向。
【数据范围】
10%的数据是题目的馈赠。
30%的数据,1≤n,m≤10。
50%的数据,1≤n,m≤50。
70%的数据,1≤n,m≤250。
100%的数据,1≤n,m≤500.
其中50%的数据是先构造出路径,再构造地图的。
100%数据是随机构造的。
考试优先队列写炸,虽然很稳,但绝对超时
code【90】
#include<stdio.h> #include<queue> #include<string.h> #include<algorithm> using namespace std; const int inf=0x3f3f3f3f; int n,m,ans=inf,mp[501][501],f[501][501]; char str[501][501]; struct node { int x,y,stp,last; }; bool vis[501][501]; bool operator<(const node &a,const node &b) { return a.stp>b.stp; } priority_queue<node> q; node st; void bfs() { st.x=1,st.y=1,st.stp=0,st.last=0; q.push(st); while(!q.empty()) { node curr=q.top(); q.pop(); int cx=curr.x,cy=curr.y,last=curr.last; if(vis[cy][cx]) continue; vis[cy][cx]=1; if(cx==m&&cy==n) { ans=curr.stp; return ; } for(int i=1;i<=4;++i) { node next=curr; if(i==1) next.y=cy-1; else if(i==2) next.y=cy+1; else if(i==3) next.x=cx-1; else if(i==4) next.x=cx+1; if(next.x>=1 && next.x<=m && next.y>=1 && next.y<=n && mp[next.y][next.x] && mp[cy][cx]!=i) { next.last=i; if(last!=i&&last!=0) next.stp=curr.stp+1; q.push(next); } } } } int main() { // freopen("run.in","r",stdin),freopen("run.out","w",stdout); memset(f,0x3f,sizeof(f)); scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { scanf("%s",str[i]+1); for(int j=1;j<=m;++j) { if(str[i][j]=='U') mp[i][j]=1; else if(str[i][j]=='D') mp[i][j]=2; else if(str[i][j]=='L') mp[i][j]=3; else if(str[i][j]=='R') mp[i][j]=4; else if(str[i][j]=='S') mp[i][j]=0; } } bfs(); if(ans==inf) printf("No Solution"); else printf("%d",ans); return 0; } // 1上 2下 3左 4右 /* 3 3 ULL LDU SUD 10 10 LDRUDDLLDU RDRRRLDLLR LURRRLLSRS LRLDULULUL RULRLLLLUR URDUDDDSDU RURLDDLDLL ULULDLURUL DLRLRDRULL LURRULURLR */