外星人打冰球的故事。
这是一道深搜的题,与一般的题不同之处在于它并不是走一格,而是走一条直线路径。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 20;
int map[MAXN+2][MAXN+2];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int w, h;
const int INF = 10e6;
int min_step = INF;
void Dfs(int x, int y, int step)
{
if (map[x][y] == 3) {
min_step = min(min_step, step);
return;
}
if (step >= min_step || step > 10) {
return;
}
int nx, ny;
int tx, ty;
for (int i = 0; i < 4; i++) {
tx = x + dx[i];
ty = y + dy[i];
nx = x;
ny = y;
while (tx >= 0 && tx < h && ty >= 0 && ty < w //判断下一位置
&& map[tx][ty] != 1) {
nx += dx[i];
ny += dy[i];
if (map[nx][ny] == 3) {
min_step = min(min_step, step);
return;
}
tx += dx[i];
ty += dy[i];
if (tx < 0 || tx >= h || ty < 0 || ty >= w) {
break;
}
if (map[tx][ty] == 1) {
map[tx][ty] = 0;
Dfs(nx, ny, step+1);
map[tx][ty] = 1;
}
}
}
}
int main()
{
int x = 0;
int y = 0;
while (scanf("%d%d", &w, &h) == 2 && w && h) {
int i, j;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
scanf("%d", &map[i][j]);
if (map[i][j] == 2) {
x = i;
y = j;
}
}
}
Dfs(x, y, 1);
if (min_step == INF) {
printf("-1\n");
}
else
printf("%d\n", min_step);
for (i = 0; i < h; i++) {
memset(map, 0, sizeof(int) * w);
}
min_step = INF;
}
return 0;
}
使用dx与dy两个数组表示冰壶的方向向量。
nx,ny表示冰壶的位置。
tx,ty用于判断冰壶的下一位置的状态。
有意思的是这道题要求最小步数,因此要搜索所有路径。
搜完某路径后要进行回溯,状态复原。