2.1 最基础的“穷竭搜索” 深度优先搜索
扔石头,上下左右四个方向如果某一个方向紧挨着block就不能扔这个方向,否则碰到block停住,block消失,再次四个方向扔。DFS老一套,不过一定要注意判断紧挨着的情况。超过最小步数剪枝也是个很有意思的技巧。
#ifndef ONLINE_JUDGE
#pragma warning(disable : 4996)
#endif
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int w, h;
int map[32][32];
int sx, sy;
int min_step;
const int direction[4][2] = {
{ -1, 0 },
{ 1, 0 },
{ 0, -1 },
{ 0, 1 },
};
void dfs(const int& x, const int& y, int step)
{
if (step >= 10 || step > min_step)
{
return;
}
for (int i = 0; i < 4; ++i)
{
int nx = x;
int ny = y;
// 让石头往固定的方向一直飞
while(nx >= 0 && nx < w && ny >= 0 && ny < h)
{
switch (map[nx][ny])
{
case 0:
{
// 继续飞
nx += direction[i][0];
ny += direction[i][1];
}break;
case 3:
{
// 到家了
if (step + 1 < min_step)
{
min_step = step + 1;
}
nx = -1;
}break;
case 1:
{
// 撞到了block
if (!(nx - direction[i][0] == x && ny - direction[i][1] == y))
{
// 中间有空地,不是紧挨着block
// 石头消失
map[nx][ny] = 0;
// 后退一步扔石头
dfs(nx - direction[i][0], ny - direction[i][1], step + 1);
// 复原地图,供下一个方向尝试
map[nx][ny] = 1;
}
// 开始下一个方向
nx = -1;
}break;
default:
break;
}
}
}
}
///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
while (cin >> w >> h, w != 0)
{
for (int i = 0; i < h; ++i)
{
for (int j = 0; j < w; ++j)
{
cin >> map[j][i];
}
}
for (int i = 0; i < h; ++i)
{
for (int j = 0; j < w; ++j)
{
if (2 == map[j][i])
{
sx = j;
sy = i;
i = h;
break;
}
}
}
map[sx][sy] = 0;
min_step = 11;
dfs(sx, sy, 0);
if (min_step > 10)
{
min_step = -1;
}
cout << min_step << endl;
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif
return 0;
}
///////////////////////////End Sub//////////////////////////////////
知识共享署名-非商业性使用-相同方式共享:码农场 » POJ 3009 Curling 2.0 《挑战程序设计竞赛(第2版)》练习题答案
码农场