• 0x25 广度优先搜索


    今天莫名不想说话。

    结果发现效率挺高?

    poj3322 本来可以1a的。。发现我宽搜写的是head<=tail而且初始是head=1,tail=2如果是多组数据简直就gg了。基础不牢固

    这题虽然看起来麻烦,但是实际上仔细思考一下是不难推出对于各种不同放在地图上的方式分别表示的。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int dx[4]={-1,0,1,0};
    const int dy[4]={0,-1,0,1};
    
    int n,m;
    char ss[510][510];
    struct node
    {
        int x,y,l,c;
    }list[1100000];
    bool check(int x,int y){return 0<x&&x<=n&&0<y&&y<=m&&ss[x][y]!='#';}
    
    bool v[510][510][3];
    int main()
    {
        int stx,sty,stl,edx,edy,edl;bool sb;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            if(n==0&&m==0)break;
            
            sb=false;
            for(int i=1;i<=n;i++)scanf("%s",ss[i]+1);
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                    if(ss[i][j]=='X'&&sb==false)
                    {
                        sb=true;
                        stx=i, sty=j;
                             if(ss[i+1][j]=='X')stl=1;
                        else if(ss[i][j+1]=='X')stl=2;
                        else stl=0;
                    }
                    else if(ss[i][j]=='O') edx=i, edy=j;
            }
            memset(v,false,sizeof(v));
            for(int i=1;i<=1000000;i++)list[i].x=list[i].y=list[i].l=list[i].c=0;
            list[1].x=stx;list[1].y=sty;list[1].l=stl;list[1].c=0;
            int head=1,tail=2;
            while(head<=tail)
            {
                if(list[head].x==edx&&list[head].y==edy&&list[head].l==0)
                {
                    printf("%d
    ",list[head].c);
                    break;
                }
                
                for(int k=0;k<=3;k++)
                {
                    node tno=list[head];tno.c++;
                    if(tno.l==0)
                    {
                        tno.x+=dx[k]<0?dx[k]*2:dx[k];
                        tno.y+=dy[k]<0?dy[k]*2:dy[k];
                        tno.l=dx[k]==0?2:1;
                    }
                    else if(tno.l==1)
                    {
                        tno.x+=dx[k]>0?dx[k]*2:dx[k];
                        tno.y+=dy[k];
                        tno.l=dx[k]==0?1:0;
                    }
                    else if(tno.l==2)
                    {
                        tno.x+=dx[k];
                        tno.y+=dy[k]>0?dy[k]*2:dy[k];
                        tno.l=dy[k]==0?2:0;
                    }
                    
                    if(check(tno.x,tno.y))
                    {
                        if(tno.l==0&&ss[tno.x][tno.y]=='E')continue;
                        if(tno.l==1&&!check(tno.x+1,tno.y))continue;
                        if(tno.l==2&&!check(tno.x,tno.y+1))continue;
                        if(v[tno.x][tno.y][tno.l]==false)
                        {
                            v[tno.x][tno.y][tno.l]=true;
                            list[tail]=tno;
                            tail++;
                        }
                    }
                }
                head++;
            }
            if(!v[edx][edy][0])printf("Impossible
    ");
        }
        return 0;
    }
    poj3322

    bzoj2252 又是gb权限题。。可以说是相当简单,让1去找0,直到全图被访问过

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int dx[4]={-1,0,1,0};
    const int dy[4]={0,-1,0,1};
    
    struct node
    {
        int x,y;
    }list[1100000];
    int d[1100][1100];
    
    char ss[1100];
    int main()
    {
        int n,m,cnt;
        scanf("%d%d",&n,&m);cnt=n*m;
        
        int head=1,tail=2;
        memset(d,-1,sizeof(d));
        for(int i=1;i<=n;i++)
        {
            scanf("%s",ss+1);
            for(int j=1;j<=m;j++)
            {
                if(ss[j]=='1')
                {
                    d[i][j]=0;
                    list[tail].x=i,list[tail].y=j;
                    tail++;
                }
            }
        }
        
        while(head<=tail)
        {
            int x=list[head].x,y=list[head].y;
            for(int k=0;k<=3;k++)
            {
                int tx=x+dx[k],ty=y+dy[k];
                if(0<tx&&tx<=n&&0<ty&&ty<=m&&d[tx][ty]==-1)
                {
                    d[tx][ty]=d[x][y]+1;
                    list[tail].x=tx,list[tail].y=ty;
                    tail++;
                }
            }
            head++;
        }
        
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<m;j++)
                printf("%d ",d[i][j]);
            printf("%d
    ",d[i][m]);
        }
        return 0;
    }
    bzoj2252

    poj1475 码量大而且麻烦,这种题是需要沉下心做的。先bfs让人到箱子周边,再让箱子bfs,实际上就是bfs套bfs,人和箱子绑成一块,记得算答案是有四种不同情况的。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int dx[4]={-1,0,1,0};
    const int dy[4]={0,-1,0,1};
    const char ch[4]={'N','W','S','E'};
    
    int n,m;
    char sc[30][30];
    struct node
    {
        int x,y,k;
    }list[410000];
    int d[30][30][4],f[30][30][4];
    char ss[30][30][4][1100];
    
    
    int xx[3100],yy[3100];
    int E[30][30];
    char sd[30][30][1100];
    bool check(int x,int y){return 0<x&&x<=n&&0<y&&y<=m&&sc[x][y]!='#';}
    int getdis(int stx,int sty,int edx,int edy,int k)
    {
        memset(E,-1,sizeof(E));
        xx[1]=stx,yy[1]=sty;E[stx][sty]=0;
        int head=1,tail=2;
        while(head<tail)
        {
            int x=xx[head],y=yy[head];
            if(x==edx&&y==edy)return E[x][y];
            for(int i=0;i<=3;i++)
            {
                int tx=x+dx[i],ty=y+dy[i];
                if(check(tx,ty)&&(tx!=edx+dx[k]||ty!=edy+dy[k])&&E[tx][ty]==-1)
                {
                    for(int o=1;o<=E[x][y];o++)sd[tx][ty][o]=sd[x][y][o];
                    sd[tx][ty][E[x][y]+1]=ch[i]+32;
                    E[tx][ty]=E[x][y]+1;
                    
                    xx[tail]=tx,yy[tail]=ty;
                    tail++;
                }
            }
            head++;
        }
        return -1;
    }
    int main()
    {
    //    freopen("a.out","w",stdout);
        int T_T=0;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            if(n==0&&m==0)break;
            printf("Maze #%d
    ",++T_T);
            
            int stpx,stpy,stbx,stby,edx,edy;
            for(int i=1;i<=n;i++)
            {
                scanf("%s",sc[i]+1);
                for(int j=1;j<=m;j++)
                         if(sc[i][j]=='S') stpx=i, stpy=j;
                    else if(sc[i][j]=='B') stbx=i, stby=j;
                    else if(sc[i][j]=='T') edx=i, edy=j;
            }
            
            int head=1,tail=1;
            memset(d,-1,sizeof(d));
            for(int i=0;i<=3;i++)
            {
                int ux=stbx+dx[i],uy=stby+dy[i];
                if(check(ux,uy))
                {
                    int dis=getdis(stpx,stpy,ux,uy,(i+2)%4);
                    if(dis==-1)continue;
                    
                    for(int o=1;o<=dis;o++)ss[stbx][stby][i][o]=sd[ux][uy][o];
                    d[stbx][stby][i]=0;
                    f[stbx][stby][i]=dis;
                    
                    list[tail].x=stbx,list[tail].y=stby,list[tail].k=i;
                    tail++;
                }
            }
            bool bk=false;int id=-1,cnt=0;
            while(head<tail)
            {
                int x=list[head].x,y=list[head].y,k=list[head].k;
                if(x==edx&&y==edy)
                {
                    if(id==-1||(d[x][y][k]<d[x][y][id]||(d[x][y][k]==d[x][y][id]&&f[x][y][k]<f[x][y][id])))
                    {
                        id=k;
                        cnt++;if(cnt==4)break;
                        bk=true;
                    }
                }
                
                int px=x+dx[k],py=y+dy[k];
                for(int i=0;i<=3;i++)
                {
                    int ux=x+dx[i],uy=y+dy[i];
                    int tx=x-dx[i],ty=y-dy[i];
                    if(check(tx,ty)&&check(ux,uy)&&(d[tx][ty][i]==-1||d[x][y][k]+1==d[tx][ty][i]))
                    {
                        int dis=getdis(px,py,ux,uy,(i+2)%4);
                        if(dis==-1||(d[x][y][k]+1==d[tx][ty][i]&&f[x][y][k]+dis>=f[tx][ty][i]))continue;
                        
                        int tot=d[x][y][k]+f[x][y][k];
                        for(int o=1;o<=tot;o++)ss[tx][ty][i][o]=ss[x][y][k][o];
                        for(int o=1;o<=dis;o++)ss[tx][ty][i][tot+o]=sd[ux][uy][o];
                        ss[tx][ty][i][tot+dis+1]=ch[(i+2)%4];
                        
                        d[tx][ty][i]=d[x][y][k]+1;
                        f[tx][ty][i]=f[x][y][k]+dis;
                        
                        list[tail].x=tx,list[tail].y=ty,list[tail].k=i;
                        tail++;
                    }
                }
                head++;
            }
            if(bk==false)printf("Impossible.
    
    ");
            else
            {
                for(int o=1;o<=d[edx][edy][id]+f[edx][edy][id];o++)printf("%c",ss[edx][edy][id][o]);
                printf("
    
    ");
            }
        }
        return 0;
    }
    poj1475
  • 相关阅读:
    [ZJOI2010] 数字计数
    [USACO] 2004 Open MooFest 奶牛集会
    数星星
    [SCOI2011] 糖果
    西瓜种植
    [NOI2018] 归程
    [APIO2012] 派遣
    小K的农场
    妮可妮可妮 [Hash]
    [ZJOI2012] 灾难
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9272188.html
Copyright © 2020-2023  润新知