码迷,mamicode.com
首页 > 其他好文 > 详细

0x25 广度优先搜索

时间:2018-07-06 11:27:48      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:get   using   alt   eve   opened   zoj   math   ons   不难   

今天莫名不想说话。

结果发现效率挺高?

 

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\n",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\n");
    }
    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\n",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\n",++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.\n\n");
        else
        {
            for(int o=1;o<=d[edx][edy][id]+f[edx][edy][id];o++)printf("%c",ss[edx][edy][id][o]);
            printf("\n\n");
        }
    }
    return 0;
}
poj1475

 

0x25 广度优先搜索

标签:get   using   alt   eve   opened   zoj   math   ons   不难   

原文地址:https://www.cnblogs.com/AKCqhzdy/p/9272188.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!