码迷,mamicode.com
首页 > Web开发 > 详细

【POJ 3009 Curling2.0 迷宫寻径 DFS】

时间:2016-04-19 06:21:26      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:

http://poj.org/problem?id=3009

模拟冰壶的移动,给出到达终点的最少投掷次数(不可达时为-1)。

具体移动规则如下:

每次选四个方向之一,沿此方向一直前进,直到撞到block或出界或抵达目标位置。

  如果撞到block,冰壶停在block的前一个位置,block消失,此时可改变冰壶的移动方向(重新投掷一次);

  如果出界,则这条移动路径以失败结束;

  如果抵达目标位置,则记录这条移动路径一共投掷的次数。

投掷次数不超过10次的为成功路径。

如果存在成功路径,输出最少的投掷次数;不存在则输出-1。

代码如下,由于数据量小,可用DFS得到所有解然后取最小值;注意回溯时还原修改过的block:

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int MAX_N = 22;
 6 
 7 int n, m;
 8 int G[MAX_N][MAX_N]; 
 9 int dx[]={0, 0, 1,-1}, dy[]={1, -1, 0, 0};
10 int sx, sy, gx, gy;
11 int min_ans;
12 
13 
14 bool inside(int x, int y){
15     if(x<0 || x>=n || y<0 || y>=m) return false;
16     return true;
17 }
18 
19 void dfs(int x, int y, int cnt){
20     if(cnt > 10) return ;
21     for(int i=0; i<4; i++){
22         int nx = x + dx[i];
23         int ny = y + dy[i];
24         if(!inside(x, y)) continue; //出界
25         if(G[nx][ny] == 1) continue; //block
26         else{
27             while(inside(nx, ny) && G[nx][ny] != 1 && G[nx][ny] != 3){    
28                 nx += dx[i];
29                 ny += dy[i]; //沿此方向走到block为止
30             }
31             if(!inside(nx, ny)) continue; //此方向最终出界
32             if(G[nx][ny] == 3){
33                 min_ans = cnt<min_ans ? cnt : min_ans;
34                 continue; //此方向中途命中
35             } 
36 
37             G[nx][ny] = 0; //block消失
38             nx -= dx[i];
39             ny -= dy[i]; //抵达此方向最后一个合法位置,block的前一个
40             //printf("%d %d\n", dx[i], dy[i]);
41             dfs(nx, ny, cnt+1);
42             nx += dx[i];
43             ny += dy[i];
44             G[nx][ny] = 1; //还原,回溯
45         }
46     }
47     return ;
48 }
49 
50 int main()
51 {
52     freopen("3009.txt", "r", stdin);
53     while(scanf("%d%d", &m, &n) != EOF){
54         if(m==0 && n==0) break;
55         for(int i=0; i<n; i++){
56             for(int j=0; j<m; j++){
57                 scanf("%d", &G[i][j]);
58                 if(G[i][j] == 2){
59                     sx = i;
60                     sy = j;
61                 }else if(G[i][j] == 3){
62                     gx = i;
63                     gy = j;
64                 }
65             }
66         }
67         
68         min_ans = 29; //任意大于10的值
69         dfs(sx, sy, 1); //投掷第一次
70         if(min_ans > 10) min_ans = -1;
71         printf("%d\n", min_ans);
72     }
73     return 0;
74 }

注意记这一类搜索的框架,以及联系算法课学过的回溯法的基本概念,如约束条件、活结点等。

【POJ 3009 Curling2.0 迷宫寻径 DFS】

标签:

原文地址:http://www.cnblogs.com/helenawang/p/5406550.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!