• 基础搜索入门(二)


    HDU_1548 A strange lift

    水题。bfs+优先队列。从一个位置到达还有一个位置的最少操作数。

    代码清单:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    struct edge
    {
        int x;
        int t;
        friend bool operator<(edge a,edge b){
            return a.t>b.t;
        }
    };
    
    int N,A,B;
    int n[205];
    int vis[205];
    void bfs()
    {
        priority_queue<edge>q;
        edge p,w;
        while(q.size()) q.pop();
        p.x=A; p.t=0;
        q.push(p);
        memset(vis,0x5f,sizeof(vis));
        vis[A]=0;
        int first=1;
        while(q.size())
        {
            p=q.top(); q.pop();
            if(p.x==B){
                first=0;
                printf("%d
    ",p.t);
                break;
            }
            w.x=p.x+n[p.x];
            w.t=p.t+1;
            if(w.x>=1&&w.x<=N&&w.t<vis[w.x])
            {
                vis[w.x]=w.t;
                q.push(w);
            }
            w.x=p.x-n[p.x];
            if(w.x>=1&&w.x<=N&&w.t<vis[w.x])
            {
                vis[w.x]=w.t;
                q.push(w);
            }
        }
        if(first) printf("-1
    ");
    }
    int main()
    {
        while(scanf("%d",&N)!=EOF)
        {
            if(N==0) break;
            scanf("%d%d",&A,&B);
            for(int i=1;i<=N;i++)
                scanf("%d",&n[i]);
            bfs();
        }return 0;
    }
    

    HDU_1728 逃离迷宫

    bfs。因为题目仅仅是说是否能到达,所以不须要使用优先队列。

    入队时仅仅要满足转弯数小于当前转弯数就可以。

    代码清单:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    struct edge{
        int x,y;
        int pos,turn;
    };
    
    int T,m,n;
    int k,x1,y1,x2,y2;
    char s[105][105];
    int vis[105][105];
    int xy[4][2]={{0,-1},{-1,0},{0,1},{1,0}};
    
    bool bfs(){
        if(x1==x2&&y1==y2) return true;
        queue<edge>q;
        while(q.size()) q.pop();
        edge p,w;
        memset(vis,0x5f,sizeof(vis));
        vis[y1][x1]=-1;
        for(int i=0;i<4;i++){
            p.x=y1+xy[i][0];
            p.y=x1+xy[i][1];
            p.pos=i;
            p.turn=0;
            if(p.x>=0&&p.x<m&&p.y>=0&&p.y<n&&s[p.x][p.y]!='*')
            {
                vis[p.x][p.y]=0; 
                q.push(p);
            }
        }
        while(q.size()){
            p=q.front(); q.pop();
            if(p.x==y2&&p.y==x2) return true;
            for(int i=0;i<4;i++){
                w.x=p.x+xy[i][0];
                w.y=p.y+xy[i][1];
                w.pos=i;
                if(w.pos!=p.pos) w.turn=p.turn+1;
                else             w.turn=p.turn;
                if(w.x>=0&&w.x<m&&w.y>=0&&w.y<n&&s[w.x][w.y]!='*'&&w.turn<=vis[w.x][w.y]&&w.turn<=k){
                    vis[w.x][w.y]=w.turn;
                    q.push(w);
                }
            }
        }
        return false;
    }
    
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&m,&n);
            for(int i=0;i<m;i++)
                scanf("%s",s[i]);
            scanf("%d%d%d%d%d",&k,&x1,&y1,&x2,&y2);
            x1-=1; y1-=1; x2-=1; y2-=1;
            if(bfs()) printf("yes
    ");
            else      printf("no
    ");
        }return 0;
    }
    

    HDU_1180 诡异的楼梯

    bfs+优先队列。注意的是到达楼梯时楼梯的状态可由 当前时间+当前朝向 来推断。

    代码清单:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    struct edge
    {
        int x,y;
        int time;
        friend bool operator<(edge a,edge b){
            return a.time>b.time;
        }
    };
    
    int m,n;
    int sx,sy;
    int ex,ey;
    int vis[25][25];
    char s[25][25];
    int xy[4][2]={{0,-1},{-1,0},{0,1},{1,0}};
    void bfs()
    {
        priority_queue<edge>q;
        while(q.size()) q.pop();
        edge p,w;
        memset(vis,0x5f,sizeof(vis));
        p.x=sx; p.y=sy; p.time=0;
        vis[sx][sy]=0;
        q.push(p);
        while(q.size())
        {
            p=q.top(); q.pop();
            //cout<<p.x<<" "<<p.y<<" "<<p.time<<endl;
            if(p.x==ex&&p.y==ey)
            {
                printf("%d
    ",p.time);
                break;
            }
    
            for(int i=0;i<4;i++)
            {
                w.x=p.x+xy[i][0];
                w.y=p.y+xy[i][1];
                if(s[w.x][w.y]=='|')
                {
                    w.x+=xy[i][0];
                    w.y+=xy[i][1];
                    if(i==1 || i==3)   // i 表示当前朝向
                    {
                        if(p.time%2==0)
                            w.time=p.time+1;
                        else
                            w.time=p.time+2;
                    }
                    else
                    {
                        if(p.time%2==0)
                            w.time=p.time+2;
                        else
                            w.time=p.time+1;
                    }
                }
                else if(s[w.x][w.y]=='-')
                {
                    w.x+=xy[i][0];
                    w.y+=xy[i][1];
                    if(i==0 || i==2)
                    {
                        if(p.time%2==0)
                            w.time=p.time+1;
                        else
                            w.time=p.time+2;
                    }
                    else
                    {
                        if(p.time%2==0)
                            w.time=p.time+2;
                        else
                            w.time=p.time+1;
                    }
                }
                else w.time=p.time+1;
                if(w.x>=0&&w.x<m&&w.y>=0&&w.y<n&&s[w.x][w.y]!='*'&&w.time<vis[w.x][w.y])
                {
                    vis[w.x][w.y]=w.time;
                    q.push(w);
                }
            }
        }
    }
    
    int main()
    {
        while(scanf("%d%d",&m,&n)!=EOF)
        {
            for(int i=0;i<m;i++)
            {
                scanf("%s",s[i]);
                for(int j=0;j<n;j++)
                {
                    if(s[i][j]=='S')
                    {
                        sx=i;
                        sy=j;
                    }
                    if(s[i][j]=='T')
                    {
                        ex=i;
                        ey=j;
                    }
                }
            }
            bfs();
        }return 0;
    }
    





  • 相关阅读:
    session
    jQuery使用ajaxStart()和ajaxStop()方法
    animate 的另一种用法 , 案例 等
    Javascript 面向对象编程(一):封装
    用事件委托获取每一个LI的索引值 有问题
    正常事件绑定与事件委托绑定
    JS 总结
    关于选项卡, 每一个TAB 标签 背景不一样的处理方式
    页面加载时的 Loading 效果
    一个计时器, 点击按钮 让他 停一会, 5s后继续自动运行
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/6843791.html
Copyright © 2020-2023  润新知