poj 3009 冰球 【DFS】求最小步数

题目链接:https://vjudge.net/problem/POJ-3009

转载于:https://blog.csdn.net/angon823/article/details/49910109

题目大意:

要求把一个冰壶从起点“2”用最少的步数移动到终点“3”,其中0为移动区域,1为石头区域,冰壶一旦想着某个方向运动就不会停止,也不会改变方向(想想冰壶在冰上滑动),除非冰壶撞到石头1 或者 到达终点 3

需要注意的是:

冰壶撞到石头后,冰壶会停在石头前面,此时(静止状态)才允许改变冰壶的运动方向,而该块石头会破裂,石头所在的区域由1变为0. 也就是说,冰壶撞到石头后,并不会取代石头的位置。

终点是一个摩擦力很大的区域,冰壶若到达终点3,就会停止在终点的位置不再移动。并且,如果步数>1,则直接算失败,这条dfs搜索路径直接舍弃。

解题分析:
这里用了dfs来求最小步数,求出所有能够到终点的解,然后用它们不断去更新步数的最小解。下列代码中,用whlie循环来代替它向一个方向走的不同步数,如果能够向前滑行,则while循环继续执行。

#include <iostream>  
#include <stdio.h>  
#include <string.h>  
#include <algorithm>
using namespace std;
int map[25][25], m, n, sx, sy;
int dir[][2] = { 1,0,-1,0,0,1,0,-1 };
int ans;
void dfs(int x, int y, int step)
{
    int nx, ny, ex, ey;   //(nx,ny) 代表下一步 (ex,ey) 代表走的这一步  
    if (step>10)return;  //实际上是剪枝  
    for (int i = 0; i<4; i++)         //向四个方向走
    {
        nx = x + dir[i][0];   //下一步  
        ny = y + dir[i][1];
        ex = x;ey = y;
        while (nx >= 0 && nx<m && ny >= 0 && ny<n && map[nx][ny] != 1)    //为真则代表这个方向能走,因为冰球紧贴冰块的那个方向不能走 
        {  
            ex += dir[i][0];       //则走这一步  
            ey += dir[i][1];
            if (map[ex][ey] == 3) //走的这步是终点吗。  
            {
                ans = min(ans, step);
                return;
            }
            nx = ex + dir[i][0];  //走完这一步的下一步  
            ny = ey + dir[i][1];
            if (nx<0 || nx >= m || ny<0 || ny >= n)
                break;          //如果下一步是越界,说明会直接滑出去,不必再进行dfs  
            if (map[nx][ny] == 1)  //如果下一步是1,进行深搜.  
            {
                map[nx][ny] = 0;
                dfs(ex, ey, step + 1);
                map[nx][ny] = 1;
            }
            //如果下一步还是0,按照题意,当然要继续滑下去,继续while,循环前进  
        }
    }
}
int main()
{
    while (~scanf("%d %d", &n, &m), m || n)
    {
        for (int i = 0; i<m; i++)
            for (int j = 0; j<n; j++)
            {
                scanf("%d", &map[i][j]);
                if (map[i][j] == 2) { sx = i; sy = j; }
            }
        ans = 0x3f3f3f3f;
        dfs(sx, sy, 1);
        if (ans == 0x3f3f3f3f)
            printf("-1\n");
        else
            printf("%d\n", ans);
    }
    return 0;
}

2018-05-27

猜你喜欢

转载自www.cnblogs.com/00isok/p/9095791.html