poj3009 Curling 2.0(dfs水题)
题目链接:http://poj.org/problem?id=3009
题目大意很简单,模拟一个冰壶比赛,给定的规则比较多,求冰壶从起点滑到终点的最少敲击次数。
规则细节如下:每次敲击冰壶后冰壶会沿一条直线滑动直到撞到障碍物(地图上的1),敲击次数不
能超过10;冰壶不能滑出给定比赛区域;如果冰壶的某个方向和障碍物直接相邻则不能往此方向移动;
如果不能到达指定地点输出-1.细节比较多,练习代码能力(代码一定要写清晰,不然不好找bug)以
及bfs的好题。其中需要注意的是冰壶到达每个点可能来自不同的方向,借助障碍物进行转换方向,所
以不能标记每个点的状态是否被访问过来判断是否dfs;还有就是再回溯的过程中要注意,冰壶如果滑
向障碍物则会停在障碍物的前一格,如果滑向终点(地图上的3)则停在终点位置,回溯的过程中不能
直接将地图更改为障碍物,而要判断是不是终点(判断3或1)。
AC代码:
#include <stdio.h> #include <algorithm> #include <string.h> #include <queue> using namespace std; #define oo 0x3f3f3f3f int maps[30][30], m, n, ans; int dir[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; bool check(int x, int y, int index) { if(x+dir[index][0]<1 || x+dir[index][0]>m) return false; if(y+dir[index][1]<1 || y+dir[index][1]>n) return false; if(maps[ x+dir[index][0] ][ y+dir[index][1] ] == 1) return false; int disx = 0, disy = 0; for(int i=1; ; i++) { disx += dir[index][0]; disy += dir[index][1]; if(x+disx<1 || x+disx>m) return false; if(y+disy<1 || y+disy>n) return false; if(maps[x+disx][y+disy]==1 || maps[x+disx][y+disy]==3) return true; } } void change(int *x, int *y, int int_x, int int_y, int index) { int disx = 0, disy = 0; for(int i=1; ; i++) { disx += dir[index][0]; disy += dir[index][1]; if(maps[int_x+disx][int_y+disy]==1) { *x = int_x+disx-dir[index][0]; *y = int_y+disy-dir[index][1]; break; } if(maps[int_x+disx][int_y+disy]==3) { *x = int_x+disx; *y = int_y+disy; break; } } } void dfs(int x, int y, int step) { if(step>10 || step>=ans) return ; if(maps[x][y] == 3) { ans = min(ans, step); return ; } for(int i=0; i<4; i++) { if(check(x, y, i)) { int nx, ny; change(&nx, &ny, x, y, i); if(maps[nx][ny] != 3) maps[nx+dir[i][0]][ny+dir[i][1]] = 0; dfs(nx, ny, step+1); if(maps[nx][ny] != 3) maps[nx+dir[i][0]][ny+dir[i][1]] = 1; } } } int main() { int sx, sy; while(scanf("%d %d", &n, &m), m||n) { for(int i=1; i<=m; i++) for(int j=1; j<=n; j++) { scanf("%d", &maps[i][j]); if(maps[i][j] == 2) { sx = i; sy = j; } } ans = oo; dfs(sx, sy, 0); if(ans == oo) ans = -1; printf("%d\n", ans); } return 0; }
浙公网安备 33010602011771号