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;
    }
  • 相关阅读:
    matplotlib 进阶之origin and extent in imshow
    Momentum and NAG
    matplotlib 进阶之Tight Layout guide
    matplotlib 进阶之Constrained Layout Guide
    matplotlib 进阶之Customizing Figure Layouts Using GridSpec and Other Functions
    matplotlb 进阶之Styling with cycler
    matplotlib 进阶之Legend guide
    Django Admin Cookbook-10如何启用对计算字段的过滤
    Django Admin Cookbook-9如何启用对计算字段的排序
    Django Admin Cookbook-8如何在Django admin中优化查询
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4534366.html
Copyright © 2011-2022 走看看