HDU1180:诡异的楼梯

传送门

题意

迷宫搜索

分析

这题写起来挺简单的,锻炼搜索基本功,一开始用记忆化搜索TLE了,改用访问标记,0ms过了,用优先队列保证终点最快达到,我会在代码中提供一些强力数据

trick

1.遇到梯子分能过(+1s)与不能过(+2s)入队列
2.一定有可行解

代码

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;

#define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a))

int m,n,sx,sy,ex,ey,ans;
char s[25];
int mp[25][25],vis[25][25];
struct node
{
    int x,y,time;
    bool operator<(const node &p)const
    {
        return time>p.time;
    }
};
int a[4][2]={0,1,1,0,0,-1,-1,0};
priority_queue<node>pq;
bool check(int x,int y)
{
    if(x<1||y<1||x>m||y>n||vis[x][y]||mp[x][y]==0) return 0;return 1;
}
void bfs()
{
    node tmp;
    tmp.x=sx,tmp.y=sy,tmp.time=0;
    while(!pq.empty()) pq.pop();
    pq.push(tmp);
    ans=0;mem(vis,0);
    vis[sx][sy]=1;
    while(!pq.empty())
    {
        tmp=pq.top();pq.pop();
        if(tmp.x==ex&&tmp.y==ey) { ans=tmp.time;return ; }
        R(i,0,4)
        {
            int xx=tmp.x+a[i][0],yy=tmp.y+a[i][1];
            if(mp[xx][yy]==2||mp[xx][yy]==3)
            {
                if(mp[xx][yy]==2)
                {
                    if((tmp.time+i)&1)
                    {
                        if(!check(xx+a[i][0],yy+a[i][1])) continue;
                        node p={xx+a[i][0],yy+a[i][1],tmp.time+1};
                        pq.push(p);vis[p.x][p.y]=1;
                        continue;
                    }
                    else
                    {
                        if(!check(xx+a[i][0],yy+a[i][1])) continue;
                        node p={xx+a[i][0],yy+a[i][1],tmp.time+2};
                        pq.push(p);vis[p.x][p.y]=1; continue;
                    }
                }
                else
                {
                    if((tmp.time+i)%2==0)
                    {
                        if(!check(xx+a[i][0],yy+a[i][1])) continue;
                        node p={xx+a[i][0],yy+a[i][1],tmp.time+1};
                        pq.push(p);vis[p.x][p.y]=1; continue;
                    }
                    else
                    {
                        if(!check(xx+a[i][0],yy+a[i][1])) continue;
                        node p={xx+a[i][0],yy+a[i][1],tmp.time+2};
                        pq.push(p);vis[p.x][p.y]=1; continue;
                    }
                }
            }
            else
            {
                if(!check(xx,yy)) continue;
                node p={xx,yy,tmp.time+1};
                vis[p.x][p.y]=1;
                pq.push(p);
            }
        }
    }
}
int main()
{
    while(scanf("%d %d",&m,&n)!=EOF)
    {
        F(i,1,m)
        {
            scanf("%s",s);
            F(j,0,n-1)
            {
                if(s[j]=='S') sx=i,sy=j+1;
                if(s[j]=='T') ex=i,ey=j+1;
                mp[i][j+1]=1;
                if(s[j]=='*') mp[i][j+1]=0;
                if(s[j]=='|') mp[i][j+1]=2;
                if(s[j]=='-') mp[i][j+1]=3;
            }
        }
        bfs();
        printf("%d\n",ans);
    }
    return 0;
}
/* 
附上几组测试数据  
5 5 
**..T 
**.*. 
**|.. 
**.** 
S..** 
5 5 
**..T 
**.*. 
**-.. 
**.** 
S..** 
5 5 
.|.-T 
-*-*| 
.*.|. 
-*-** 
S|.** 
5 5 
S.... 
-|-|- 
..... 
-|-|- 
....T 
1 3 
S-T 
1 3 
S|T 
1 5 
S|.|T 
1 5 
S-.-T 
1 5 
S|.-T 
1 5 
S-.|T 
答案是: 
8 7 7 8 1 2 4 3 3 2 
 
*/  

posted @ 2017-04-05 23:19  遗风忘语  阅读(284)  评论(0编辑  收藏  举报