(水)POJ-3009 DFS+回溯

来源:互联网 发布:网络服务器机柜 品牌 编辑:程序博客网 时间:2024/04/28 21:21

题目大意:给一个n*m的图,给定起点及目的地,每次往某个方向滑动后只有撞到石头才会停下,且石头会被撞毁,如果出界则不能这样走。问做少滑动多少次能到目的地,且限制了最多滑10次(用来剪枝)(注意,滑动次数不是指走一格算一次,还是从开始滑动到停下才算一次)

题目链接:点击打开链接

分析:用dfs,每次枚举4个方向,若没有停下则一直前进直到停下进入下一次递归,同时记录下被撞到的石头被摧毁,返回时再将此石头恢复就行(利用回溯的思想),若出界则此方向不能走continue就行

直接上代码:

#include<cstdio>                 //POJ3009 dfs+经典回溯#include<algorithm>using namespace std;#define Max 20+5#define Minus_1 -1int a[Max][Max];int sx, sy, ex, ey, ans = 11;struct point{int first, second;}p[4] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };void dfs(int x, int y, int step, int turn){if (step > 10) return;for (int i = 0; i < 4; i++)       //枚举4个方向{int flag = 0;int r = x + p[i].first, v = y + p[i].second;flag++;while (a[r][v] == 0) { r = r + p[i].first; v = v + p[i].second; flag++; }  //只要此方向下一格为0,就一直往此方向走if (a[r][v] == 1 && flag > 1){a[r][v] = 0;dfs(r - p[i].first, v - p[i].second, step + 1, i);a[r][v] = 1;}if (a[r][v] == Minus_1) continue;if (a[r][v] == 3 && step + 1 < ans) { ans = step + 1; return; }}return;}int main(){int W, H;while (scanf("%d%d", &W, &H)){if (W == 0 && W == 0) break;ans = 11;memset(a, Minus_1, sizeof(a));for (int i = 1; i <= H; i++)for (int j = 1; j <= W; j++){scanf("%d", &a[i][j]);if (a[i][j] == 2) { sx = i, sy = j; }if (a[i][j] == 3) { ex = i, ey = j; }}a[sx][sy] = 0;dfs(sx, sy, 0, 4);printf("%d\n", ans <= 10 ? ans : -1);}return 0;}


0 0
原创粉丝点击