poj-3009-Curling 2.0-dfs

来源:互联网 发布:mac 触摸板 手势 编辑:程序博客网 时间:2024/06/05 09:51

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

上下左右四联通块,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 9000int 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\n");   else printf("%d\n", ans);}int main(){   while(scanf("%d%d", &w, &h) != EOF && h && w){      work();   }   return 0;}



0 0