zoukankan      html  css  js  c++  java
  • hdu

    http://acm.hdu.edu.cn/showproblem.php?pid=1728

    这两道题花了一下午的时候调试,因为以前做过类似的题,但是判断方向的方法是错的,一直没发现啊,真无语。

    每个状态除了坐标外还需要记录步数,和方向。还要注意输入格式。

    并且每一个点并不是走过了就不能在走,只要到达这个点的时候转向次数少的就可以更新这个点,可以等于。千万注意这个坑。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 using namespace std;
     5 int n,m,k;
     6 int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
     7 char mp[110][110];
     8 int used[110][110];
     9 struct point
    10 {
    11     int x,y,d,time;
    12     bool operator < (const point a) const
    13     {
    14         return time>a.time;
    15     }
    16 };
    17 void bfs(int x1,int y1,int x2,int y2)
    18 {
    19     //printf("%d %d %d %d
    ",x1,y1,x2,y2);
    20     for(int i=0;i<=n;i++)
    21         for(int j=0;j<=m;j++) used[i][j]=1<<29;
    22     priority_queue<point>que;
    23     point s;
    24     s.x=x1,s.y=y1,s.d=-1,s.time=0;
    25     que.push(s);
    26     used[s.x][s.y]=0;
    27     while(!que.empty())
    28     {
    29         point e=que.top(); que.pop();
    30         printf("%d %d %d
    ",e.x,e.y,e.time);
    31         if(e.time>k) continue;
    32         if(e.x==x2&&e.y==y2) {printf("yes
    ");return;}
    33         for(int i=0;i<4;i++)
    34         {
    35             s.x=e.x+dir[i][0];
    36             s.y=e.y+dir[i][1];
    37             if(s.x<0||s.x>=n||s.y<0||s.y>=m||mp[s.x][s.y]=='*') continue;
    38             s.d=i;
    39             if(s.d!=e.d&&e.d!=-1)  //转向次数加1   并且保证不会往回走构成死循环
    40             {
    41                 s.time=e.time+1;
    42             }
    43             else s.time=e.time;
    44             if(s.time<=used[s.x][s.y]&&s.time<=k) //注意
    45             {
    46                 used[s.x][s.y]=s.time;
    47                 que.push(s);
    48             }
    49         }
    50     }
    51     printf("no
    ");
    52 }
    53 
    54 int main()
    55 {
    56     freopen("a.txt","r",stdin);
    57     int t,x1,y1,x2,y2;
    58     scanf("%d",&t);
    59     while(t--)
    60     {
    61         scanf("%d%d",&n,&m);
    62         getchar();
    63         for(int i=0;i<n;i++)
    64             scanf("%s",&mp[i]);
    65         scanf("%d",&k);
    66         scanf("%d%d%d%d",&y1,&x1,&y2,&x2);
    67         //printf("%d %d %d %d
    ",x1-1,y1-1,x2-1,y2-1);
    68         bfs(x1-1,y1-1,x2-1,y2-1);
    69     }
    70     return 0;
    71 }

    知道写bfs了 换成dfs还是挺容易的。

    并且bfs是1400ms,dfs只有31ms。

    #include <cstdio>
    #include <cstring>
    char mp[110][110];
    int n,m,k;
    int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
    int x2,y2;
    bool flag;
    int vis[110][110];
    
    void dfs(int x,int y,int d,int step)
    {
        //printf("%d %d %d %d
    ",x,y,d,step);
        if(flag) return;
        if(x==x2&&y==y2&&step<=k)
        {
            flag=1;
            printf("yes
    ");
            return;
        }
        for(int i=0;i<4;i++)
        {
            int xx=x+dir[i][0];
            int yy=y+dir[i][1];
            int dd=i;
            if(xx>=0&&xx<n&&yy>=0&&yy<m&&mp[xx][yy]!='*')
            {
                int s=step;
                if(d!=dd&&d!=-1) s++;
                if(s<=vis[xx][yy]&&s<=k)  //强力的剪枝  
                {
                    vis[xx][yy]=s;
                    dfs(xx,yy,dd,s);
                }
            }
        }
    }
    int main()
    {
       // freopen("a.txt","r",stdin);
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++) scanf("%s",mp[i]);
            int x1,y1;
            scanf("%d%d%d%d%d",&k,&y1,&x1,&y2,&x2);
            flag=0;
            for(int i=0;i<=n;i++)
                for(int j=0;j<m;j++) vis[i][j]=1<<29;
            x1--,y1--;
            x2--,y2--;
            vis[x1][y1]=0;
            dfs(x1,y1,-1,0);
            if(!flag) printf("no
    ");
        }
        return 0;
    }

    http://acm.hdu.edu.cn/showproblem.php?pid=1175

    这个题的坑点在于只能两个端点是非0数,不能经过其他的数字。

    思路是一样的。

    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    int n,m;
    int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
    int mp[1010][1010];
    int used[1010][1010];
    struct point
    {
        int x,y,d,time;
        bool operator < (const point a) const
        {
            return time>a.time;
        }
    };
    point t;
    bool bfs(point s)
    {
        for(int i=0;i<=n;i++)
            for(int j=0;j<=m;j++) used[i][j]=1<<29;
        priority_queue<point>que;
        que.push(s);
        used[s.x][s.y]=0;
        while(!que.empty())
        {
            point e=que.top(); que.pop();
    
            if(e.x==t.x&&e.y==t.y) return true;
            for(int i=0;i<4;i++)
            {
                s.x=e.x+dir[i][0];
                s.y=e.y+dir[i][1];
                s.d=i;
    
                if(s.x<1||s.x>n||s.y<1||s.y>m) continue;
                if(mp[s.x][s.y]!=0&&(s.x!=t.x||s.y!=t.y)) continue;  //注意别逻辑别写错了
                //printf("%d %d %d
    ",s.x,s.y,s.time);
                if(s.d!=e.d&&e.d!=-1) s.time=e.time+1;
                else s.time=e.time;
                if(s.time<=used[s.x][s.y]&&s.time<=2)
                {
                    used[s.x][s.y]=s.time;
                    que.push(s);
                }
            }
        }
        return false;
    }
    
    int main()
    {
       //freopen("a.txt","r",stdin);
        int q,x1,y1,x2,y2;
        while(~scanf("%d%d",&n,&m))
        {
            if(n==0&&m==0) break;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++) scanf("%d",&mp[i][j]);
            scanf("%d",&q);
            while(q--)
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                if(!mp[x1][y1]||mp[x1][y1]!=mp[x2][y2]) printf("NO
    ");
                else
                {
                    point s;
                    s.x=x1,s.y=y1,s.d=-1,s.time=0;
                    t.x=x2,t.y=y2;
                    if(bfs(s)) printf("YES
    ");
                    else printf("NO
    ");
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    ossec配置使用腾讯企业邮箱告警
    网络排除工具之tcping
    pyenv 安装
    CVE-2020-1472 漏洞检测
    容器技术的核心
    简述 进程、线程、协程的区别 以及应用场景--记录
    php函数使用
    php使用表单post方法进行页面
    CURL方式使用代理访问网站
    nginx下隐藏admin和当前域名下得index.php
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4534366.html
Copyright © 2011-2022 走看看