zoukankan      html  css  js  c++  java
  • POJ 3278&&2049&&3083

      这次的题目叫图的深度&&广度优先遍历。

      然后等我做完了题发现这是DFS&&BFS爆搜专题。

      3278:题目是经典的FJ,他要抓奶牛。他和牛(只有一头)在一条数轴上,他们都站在一个点上(坐标为0~1e5)。假设FJ的位置为x,他每次可以去x+1,x-1,x*2的地方。问他最少走几次才能抓到他的牛(牛不会动)。

      赤裸裸的BFS,注意判断是否越界(很容易RE)

      CODE

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=100000;
    int q[N*3+10],step[N+5],n,k;
    bool vis[N+5];
    inline void read(int &x)
    {
        x=0; char ch=getchar();
        while (ch<'0'||ch>'9') ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    }
    int main()
    {
        read(n); read(k);
        memset(vis,true,sizeof(vis));
        if (n>=k) printf("%d",n-k); else
        {
            int head=0,tail=1;
            q[1]=n; step[n]=0; vis[n]=0;
            while (head<tail)
            {
                int now=q[++head];
                if (now==k) { printf("%d",step[now]); break; }
                if (now+1<=N) if (vis[now+1]) vis[now+1]=0,q[++tail]=now+1,step[now+1]=step[now]+1;
                if (now-1>=0) if (vis[now-1]) vis[now-1]=0,q[++tail]=now-1,step[now-1]=step[now]+1;
                if (now*2<=N) if (vis[now*2]) vis[now*2]=0,q[++tail]=now*2,step[now*2]=step[now]+1;
            }
        }
        return 0;
    }

      2049:一道迷宫BFS,和今年NOIP PJ T3 有点类似。题意可以百度翻译(这道题翻译的还是很好的,至少能看懂)

      因为他给出的是网格的边而不是点,所以要进行转化。

      我们用a[x][y][0]表示(x,y)右方向的边的属性(墙或门或空地),a[x][y][1]表示(x,y)上方向的边的属性(同理)

      建图玩了以后可以再连边跑SPFA或者直接松弛BFS(循环更新到每个点的的最小通过门数)

      最后提醒那个人有可能不在迷宫里,就直接输出0

      CODE

    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int N=205,INF=1e9,fx[4]={0,1,-1,0},fy[4]={1,0,0,-1};
    int a[N][N][2],f[N][N],q[N*N*10+10][2],n,m,i,j,x,y,d,t;
    double s_x,s_y;
    inline void read(int &x)
    {
        x=0; char ch=getchar(); int flag=1;
        while (ch<'0'||ch>'9') { if (ch=='-') flag=-1; ch=getchar(); }
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        x*=flag;
    }
    int main()
    {
        for (;;)
        {
            read(n); read(m);
            if (n==-1&&m==-1) break;
            for (i=0;i<N;++i)
            for (j=0;j<N;++j)
            f[i][j]=INF,a[i][j][0]=a[i][j][1]=2;
            for (i=1;i<=n;++i)
            {
                read(x); read(y); read(d); read(t);
                if (d) 
                {
                    for (j=y;j<y+t;++j)
                    a[x][j][1]=0;
                } else
                {
                    for (j=x;j<x+t;++j)
                    a[j][y][0]=0;
                }
            }
            for (i=1;i<=m;++i)
            {
                read(x); read(y); read(d);
                if (d) a[x][y][1]=1; else a[x][y][0]=1;
            }
            scanf("%lf%lf",&s_x,&s_y);
            x=floor(s_x); y=floor(s_y);
            if (x<0||y<0||x>199||y>199||(!n&&!m)) { puts("0"); continue; }
            int head=0,tail=1;
            q[1][0]=x; q[1][1]=y; f[x][y]=0;
            while (head<tail)
            {
                x=q[++head][0]; y=q[head][1];
                for (i=0;i<4;++i)
                {
                    int xx=x+fx[i],yy=y+fy[i];
                    if (xx<0||yy<0||xx>200||yy>200) continue;
                    if (i==0)
                    {
                        if (a[xx][yy][0]==2) if (f[xx][yy]>f[x][y]) q[++tail][0]=xx,q[tail][1]=yy,f[xx][yy]=f[x][y];
                        if (a[xx][yy][0]==1) if (f[xx][yy]>f[x][y]+1) q[++tail][0]=xx,q[tail][1]=yy,f[xx][yy]=f[x][y]+1;
                    } 
                    if (i==1)
                    {
                        if (a[xx][yy][1]==2) if (f[xx][yy]>f[x][y]) q[++tail][0]=xx,q[tail][1]=yy,f[xx][yy]=f[x][y];
                        if (a[xx][yy][1]==1) if (f[xx][yy]>f[x][y]+1) q[++tail][0]=xx,q[tail][1]=yy,f[xx][yy]=f[x][y]+1;
                    }
                    if (i==2)
                    {
                        if (a[x][y][1]==2) if (f[xx][yy]>f[x][y]) q[++tail][0]=xx,q[tail][1]=yy,f[xx][yy]=f[x][y];
                        if (a[x][y][1]==1) if (f[xx][yy]>f[x][y]+1) q[++tail][0]=xx,q[tail][1]=yy,f[xx][yy]=f[x][y]+1;
                    }
                    if (i==3)
                    {
                        if (a[x][y][0]==2) if (f[xx][yy]>f[x][y]) q[++tail][0]=xx,q[tail][1]=yy,f[xx][yy]=f[x][y];
                        if (a[x][y][0]==1) if (f[xx][yy]>f[x][y]+1) q[++tail][0]=xx,q[tail][1]=yy,f[xx][yy]=f[x][y]+1;
                    }
                }
            }
            if (f[0][0]==INF) puts("-1"); else printf("%d
    ",f[0][0]);
        }
        return 0;
    }

      3083:这是一道神坑题,完美的展示了爆搜的含义。

      题意是一个图,S起点,E终点,.是空地,#是墙不能走。问从S到E左优先和右优先以及最短步数是多少。

      DFS+BFS。BFS最短和简单,终点的DFS。

      因为他要求遵循左右的性质,所以方向数组的定义就很玄学了

      以左优先为例 如果现在的方向是↑,那么优先级就是←↑→↓,其他方向同理(能左转就左转,不能转就向右转再判断),右优先同理。

      因此预处理一下坐标的顺序就很水了。

      CODE

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N=45,
    l[4][4]=
    {
        {3,0,1,2},
        {0,1,2,3},
        {1,2,3,0},
        {2,3,0,1},
    },
    r[4][4]=
    {
        {1,0,3,2},
        {2,1,0,3},
        {3,2,1,0},
        {0,3,2,1},
    },
    fx[4]={0,-1,0,1},fy[4]={-1,0,1,0};
    char a[N][N];
    int q[N*N*10+10][2],step[N][N],i,j,n,m,s_x,s_y,e_x,e_y,t,w,l_ans,r_ans,min_ans;
    bool vis[N][N],flag;
    inline void read(int &x)
    {
        x=0; char ch=getchar();
        while (ch<'0'||ch>'9') ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    }
    inline void l_DFS(int x,int y,int w,int s)
    {
        if (flag) return;
        if (x==e_x&&y==e_y) { l_ans=s; flag=1; return; }
        for (int i=0;i<4;++i)
        {
            int xx=x+fx[l[w][i]],yy=y+fy[l[w][i]];
            if (xx<=0||yy<=0||xx>n||yy>m) continue;
            if (a[xx][yy]=='#') continue;
            l_DFS(xx,yy,l[w][i],s+1);
        }
    }
    inline void r_DFS(int x,int y,int w,int s)
    {
        if (flag) return;
        if (x==e_x&&y==e_y) { r_ans=s; flag=1; return; }
        for (int i=0;i<4;++i)
        {
            int xx=x+fx[r[w][i]],yy=y+fy[r[w][i]];
            if (xx<=0||yy<=0||xx>n||yy>m) continue;
            if (a[xx][yy]=='#') continue;
            r_DFS(xx,yy,r[w][i],s+1);
        }
    }
    inline void BFS(int s_x,int s_y)
    {
        memset(step,0,sizeof(step));
        memset(vis,true,sizeof(vis));
        int head=0,tail=1;
        q[1][0]=s_x; q[1][1]=s_y;  step[s_x][s_y]=1; vis[s_x][s_y]=0;
        while (head<tail)
        {
            int x=q[++head][0],y=q[head][1];
            if (x==e_x&&y==e_y) { min_ans=step[x][y]; return; }
            for (int i=0;i<4;++i)
            {
                int xx=x+fx[i],yy=y+fy[i];
                if (xx<=0||yy<=0||xx>n||yy>m) continue;
                if (a[xx][yy]=='#'||!vis[xx][yy]) continue;
                q[++tail][0]=xx; q[tail][1]=yy; step[xx][yy]=step[x][y]+1; vis[xx][yy]=0;
            }
        }
    }
    int main()
    {
        read(t);
        while (t--)
        {
            read(m); read(n);
            for (i=1;i<=n;++i)
            for (j=1;j<=m;++j)
            {
                cin>>a[i][j];
                if (a[i][j]=='S') s_x=i,s_y=j;
                if (a[i][j]=='E') e_x=i,e_y=j;
            }
            if (s_x==1) w=3; if (s_x==n) w=1; if (s_y==1) w=2; if (s_y==m) w=0;
            flag=0; l_DFS(s_x,s_y,w,1); 
            flag=0; r_DFS(s_x,s_y,w,1); 
            BFS(s_x,s_y);
            printf("%d %d %d
    ",l_ans,r_ans,min_ans);
        }
        return 0;
    }
  • 相关阅读:
    生成器
    ELK出现unassigned_shards解决办法
    ElK集群 采集 redis 数据
    postgresql-12编译安装
    openshift 3.11安装部署
    Linux TCP漏洞 CVE-2019-11477 CentOS7 修复方法
    zabbix-server安装部署配置
    zabbix-proxy安装部署
    harbor镜像仓库-02-https访问配置
    harbor镜像仓库-01-搭建部署
  • 原文地址:https://www.cnblogs.com/cjjsb/p/8444969.html
Copyright © 2011-2022 走看看