http://poj.org/problem?id=3009
扔冰球
最开始没看懂示例数据 才发现相邻有墙时不能扔
程序一定要有很好的可读性 要说清楚 不然越改越烦
具体思路:
每撞到墙 墙体会消失 地图在发生改变 所以不能广搜
深度+回溯
因为深搜会搜出所有可能的投掷方案 所以step <= 10作为剪枝
每一个格子有4种方向 4^10 = 10^6绰绰有余
选择一个方向投掷 检测是否越界 检测是否可以投掷 检测是否到终点---->>>.更新终点步数
继续搜索的情况---->>>撞到墙壁 ->击碎墙壁->继续搜索->回溯->修复墙壁->下一个方向
//终于在看了别人的代码后过了 这种混了模拟的题 一定不要慌 不要一堆条件
//条理is so important 不然就要找bug找死(流程图first)
//写得越简单越好 越清晰越好 god!!
1 #include <iostream> 2 #include <stdio.h> 3 4 using namespace std; 5 6 const int INF = 0x3f3f3f3f; 7 int N,M; 8 int goal = INF; 9 int board[25][25]; 10 int d[4][2] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1} }; 11 int sx,sy,ex,ey; 12 13 14 bool check(int x, int y)//检查是否越界 15 { 16 if (x < 0 || y < 0 || x >= M || y >= N) return false; 17 return true; 18 } 19 20 void dfs(int step, int x, int y) 21 { 22 int nx, ny; 23 if (step > 10) return ;//剪枝 24 for (int i = 0; i < 4; i++) 25 { 26 nx = x + d[i][0]; 27 ny = y + d[i][1]; 28 if (!check(nx,ny)) continue;//越界 29 if(board[nx][ny] == 1) continue;//直接遇到墙了 30 while (!board[nx][ny]) 31 { 32 nx += d[i][0]; 33 ny += d[i][1]; 34 if (!check(nx,ny)) break;//如果越界就退出 35 } 36 if (check(nx,ny))//如果没有越界 37 { 38 if (board[nx][ny] == 3)//如果到终点了 39 { 40 goal = min(goal, step); 41 } 42 if (board[nx][ny] == 1) 43 { 44 board[nx][ny] = 0;//击碎岩石 45 dfs(step+1, nx-d[i][0], ny-d[i][1]); 46 board[nx][ny] = 1;//回溯修复岩石 47 } 48 } 49 } 50 } 51 52 int main() 53 { 54 freopen("in.txt", "r", stdin); 55 while ( ~scanf("%d%d", &N, &M) ) 56 { 57 if (M == 0 && N == 0) break; 58 for(int i = 0; i < M; i++) 59 { 60 for (int j = 0; j < N; j++) 61 { 62 scanf( "%d", &board[i][j] ); 63 if (board[i][j] == 2) 64 { 65 sx = i; 66 sy = j; 67 board[i][j] = 0; 68 }//起点就是一个起始的地方和0没有区别 69 if (board[i][j] == 3) 70 { 71 ex = i; 72 ey = j; 73 } 74 } 75 } 76 goal = INF; 77 dfs(1, sx, sy); 78 if (goal != INF) printf("%d\n", goal); 79 else printf("-1\n"); 80 } 81 return 0; 82 }
原文:http://www.cnblogs.com/oscar-cnblogs/p/6295111.html