• [原]poj-3009-Curling 2.0-dfs


    题目太长就不贴了,题意:

    上下左右四联通块,2表示起点,3表示终点,1为block,0为空地,每动一次冰壶,冰壶就会向推动的方向一直移动,直到碰到block或出界,如果碰到block就在block前停下来,同时block消失,如果出界则失败,输出-1,同时,如果在10次推动内都没达到终点也失败,输出-1。如果成功,则输出最少推动次数。


    思路:

    有四种情况:1,冰壶起点周围没有空地,不能推动,失败;   2,冰壶周围有空地可以移动,则进行对周围进行dfs,情况有三,①直接遇到终点、②碰到block、③出界。


    总结:

    被这题难住的地方有  :①冰壶可以一直移动,②block会消失,所以如果dfs不成功,还要复原,③对于一开始就不能移动的冰壶做判断。对于第一种情况用一趟while()一直对一个方向更新坐标直到边界条件或下次dfs起点,就解决了;对于第二种情况,可以看下面的AC代码,其实每次冰壶碰到block之后让block消失,然后重新dfs,但在dfs返回时再复原就好了,这时 ans 已经记录下最少移动次数的信息,对于block存不存在对结果没有影响,自己可以思考一下;情形三,则作一判断   !( nx-dir[i][0] == x && ny-dir[i][1] == y ),具体看下面的代码。

    当把上面的情况理清之后,就是一道很基础的dfs了~

    下面是AC代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define maxn 30
    #define INF 9000
    int d[4][2] = { 0,1, 0, -1, 1, 0, -1, 0 };
    int bo[maxn][maxn];
    int w, h, ans;
    bool check(int a, int b)
    {
       if(a >= 0 && b >= 0 && a < h && b < w) return true;
       return false;
    }
    int x;
    void dfs(int a, int b, int rec)
    {
       if(rec > 10 || rec > ans) return;
       for(int i = 0; i < 4; i++)
       {
          int dx = a + d[i][0];
          int dy = b + d[i][1];
          if(check(dx, dy) && (bo[dx][dy] == 0 || bo[dx][dy] == 2|| bo[dx][dy] == 3)){
             bool flag = 0;//cout<<i<<endl;
             while(bo[dx][dy] != 1 && bo[dx][dy] != 3){
                dx += d[i][0];
                dy += d[i][1];
                if(!check(dx, dy)) {
                   flag = 1;
                   break;
                }
             }
    
             if(flag) continue;
             if(bo[dx][dy] == 1) {
                bo[dx][dy] = 0;
                dfs(dx-d[i][0], dy-d[i][1], rec+1);
                bo[dx][dy] = 1;
             }
             if(bo[dx][dy] == 3){
                if(ans > rec) ans = rec;
                return;
             }
          }
       }
    }
    void work()
    {
       int sx, sy;
       for(int i = 0; i < h; i++){
          for(int j = 0; j < w; j++){
             scanf("%d", &bo[i][j]);
             if(bo[i][j] == 2) sx = i, sy = j;
          }
       }
       ans = INF;
       dfs(sx, sy, 1);
       if(ans == INF) printf("-1
    ");
       else printf("%d
    ", ans);
    }
    int main()
    {
       while(scanf("%d%d", &w, &h) != EOF && h && w){
          work();
       }
       return 0;
    }
    



    作者:u011652573 发表于2014-4-15 22:42:28 原文链接
    阅读:61 评论:0 查看评论
  • 相关阅读:
    openGL 纹理05
    音视频系列文章
    webrtc系列文章
    ! [rejected] master -> master (non-fast-forward)
    openGL 预定义变量04
    Android项目实战--手机卫士24--程序锁的实现以及逻辑
    大数记录之,大数乘整型数nyoj832
    与IO相关的等待事件troubleshooting-系列9
    发布文章时多少天、多少小时、多少分前发布功能
    CSS3之边框图片border-image
  • 原文地址:https://www.cnblogs.com/ZiningTang/p/3834750.html
Copyright © 2020-2023  润新知