传送门
// 题意: 一个矩阵, 从2到3, 1是墙, 每次将这个冰壶往一个方向扔出去, 这个冰壶是有在碰到了石头才会停下来, 并且被撞的石头消失, 或者冰壶出界. 问最多扔10次问到达终点的最少扔的次数是多少..
思路: 这个很多人一眼看最短, bfs没跑了, 但是我们要注意这个图是会发生改变的, bfs同时的多个状态进行会影响图的, 从而影响答案, 所以我们看10次, 图的大小, 因为用深搜来解决是最好的, 那么我们注意这个冰壶一直往同个方向走的操作, 注意怎么写回溯的过程才不会影响哈…. 具体参照代码…
AC Code
const int maxn = 20+5;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
int s[maxn][maxn];
int n, m;
int sx, sy;
bool ok(int x, int y) {
return x >= 1 && x <= n && y >= 1 && y <= m && s[x][y] != 1;
}
int ans;
void dfs(int x, int y, int deep) {
if (deep > 10) return ;
for (int i = 0 ; i < 4 ; i ++) {
int xx = x + dx[i];
int yy = y + dy[i];
while(ok(xx, yy)) {
while(ok(xx, yy) && s[xx][yy] != 3) { // 这样写时最好的....
xx += dx[i];
yy += dy[i];
}
if (s[xx][yy] == 3) {
ans = min(ans, deep);
return ;
}
if (s[xx][yy] == 1) {
s[xx][yy] = 0;
dfs(xx-dx[i], yy-dy[i], deep+1);
s[xx][yy] = 1;
}
}
}
}
void solve()
{
while(~scanf("%d%d", &m, &n)) {
if (n + m == 0) break;
ans = inf; Fill(s, 0);
for (int i = 1 ; i <= n ; i ++) {
for (int j = 1 ; j <= m ; j ++) {
scanf("%d", &s[i][j]);
if (s[i][j] == 2) {
sx = i;
sy = j;
}
}
}
dfs(sx, sy, 1);
printf("%d\n", ans == inf?-1:ans);
}
}