小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

*/
posted @ 2018-10-14 17:28  qseer  阅读(156)  评论(0编辑  收藏  举报