poj3009(dfs/bfs)

来源:互联网 发布:c语言函数大全 编辑:程序博客网 时间:2024/05/06 18:53

题目描述:点击打开链接

/*translation:题目给出冰壶初始位置,以及目标位置。要求以最短的步数将冰壶移动到目标位置。注意冰壶每往一个方向走上一步,就将一直往这个方向移动知道碰上障碍。碰到障碍时,障碍本身也被击碎。求出最短的步数是多少??solution:dfs,回溯,剪枝要求最短路径的第一反映是用bfs,但这道题用dfs + 剪枝也能求出来。因为是求最优解,所以每次找到一个解时就必须对全局变量ans进行更新。所以很自然这道题便采用void类型的dfs。另外由于步数大于10就必须退出(因为大于10的步数在题目中是非法的),所以这道题用void类型的dfs就不存在死循环爆栈的问题。note:1:void类型的dfs一旦处理不好边会陷入死循环导致爆栈。所以什么时候要return一定要处理好。此题由于步数不能大于10这个限制条件的存在,所以肯定不会死循环!2:冰壶移动时一定是向空位移动的,碰到障碍停下同时障碍被击碎。但是冰壶的前进方向的下一步是障碍时冰壶便不能往这个方向移动。*/#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn = 25;const int INF = 1<<30;const int E = 0;const int S = 1;const int W = 2;const int N = 3;int w, h, G[maxn][maxn];int ans;int dirx[] = {0, 1, 0, -1};int diry[] = {1, 0, -1, 0};int start_row, start_col;int end_row, end_col;inline bool inside(int r, int c) {return r >= 0 && r < h && c >= 0 && c < w;}void dfs(int row, int col, int cnt) {if(cnt > 10)return;//noteint tr, tc;for(int d = 0; d < 4; d++) {tr = row;tc = col;if(G[tr + dirx[d]][tc + diry[d]] == 1)continue;//notebool flag = true;for(;;) {tr += dirx[d];tc += diry[d];if(!inside(tr, tc)) { flag = false; break; }if(G[tr][tc] == 1)break;if(G[tr][tc] == 3) {ans = min(ans, cnt + 1);return;}}if(!flag)continue;G[tr][tc] = 0;//击碎障碍dfs(tr - dirx[d], tc - diry[d], cnt + 1);G[tr][tc] = 1;}}int main(){//freopen("in.txt", "r", stdin);    while(~scanf("%d%d", &w, &h) && w && h) {for(int i = 0; i < h; i++) {for(int j = 0; j < w; j++) {scanf("%d", &G[i][j]);if(G[i][j] == 2) {start_row = i;start_col = j;}if(G[i][j] == 3) {end_row = i;end_col = j;//start position & end position}}}ans = INF;dfs(start_row, start_col, 0);if(ans > 10)printf("-1\n");elseprintf("%d\n", ans);    }    return 0;}


0 0
原创粉丝点击