hdu 1010 Tempter of the Bone 解题报告

很长时间都没有写过解题报告了,不知怎么了今天忽然想到了要写一篇解题报告算了不说废话了。hdu 1010题

题意:在一个矩形方格中有一个门用S标示,有一个出口用D标示,X标示这个格子不能通过,. 标示这个格子可以通过。给出这个的一个矩形方格问能否在规定的时间到达D(一个格子可以重复的走但是不能在格子上停留)。

分析:这是一个搜索的题目,在搜索的过程中要用到奇偶剪枝法(可以百度一下什么是奇偶剪枝法)。

在这里主要想说一说搜索算法(是个人理解呵),搜索主要用来在一个搜索的空间中找到一个可行的解。总是觉得搜索的过程和数学中的分步计数法挺像的。在分步计数法中每一步都有多种的选择,这和搜索中的过程是一样的。就像我们选择专业方向一样,首先我们要选个一个大的专业领域,是经济学还是会计学,或者是IT行业。但是在IT行业中还有很多的专业,是计算机科学与技术还是软件工程或者是信息管理系统,再或者是物联网专业,假如你选择了计算机科学与技术。在这个专业里还是有很多的方向的,你还是要继续做出选择的。他也是一个多阶段决策的过程,在这一点上他和动态规划是一样的,只是动态规划对问题的性质有了一些限制(比如问题必需要满足最优子结构的性质和无后效性才能使用动态规划算法)。当然使用动态规划算法效率要比搜索的效率快很多。剪枝的作用就是要避免一些没有必要的试探,什么是没有必要的试探:就是当你做出了这个选择之后无论后面你再做出什么样的选择都不会是可行解。

最基本的剪枝就是用对边界条件的限制来进行剪枝,剪枝的时候记着一个原则就行了下面我用这个题目来讲解一下

先看代码:

#include 
#include 
#include 
#include 
#include 
using namespace std;

const int maxn = 20+5;
char map[maxn][maxn];
bool visit[maxn][maxn], flag;
int n, m, T;
int tmp[][2] = {{-1,0},{1,0},{0,-1},{0,1}};
int start_x, start_y, end_x,end_y;

void dfs(int i, int j, int cur)
{
    if(i<1 || i>n || j<1 || j>m || visit[i][j])return;
    //这个是用对边界条件的限制进行的剪枝以及这个位置在这以前是否到达过。
    if(map[i][j] == 'X')return;
    //这个是用题目中的意思这个位置是不能通过的进行剪枝。
    int tmp1 = T-cur-(abs(end_x-i)+abs(end_y-j));
    if(tmp1<0 || tmp1&1)return;
    //这个是奇偶剪枝
    if(cur == T && map[i][j] == 'D')
    {
        flag = true; return;
    }
    //这个是用这个位置就是最终想要的位置进行剪枝。
    if(cur >= T)return;
    //这个是用题目中所说的必须要在T时间的时刻到达进行剪枝。
    if(flag)return;
    //这个是用到达这个位置时已经找到了一个可行解了不需要再进行搜索了进行剪枝。
    //如果程序执行到这儿就说明这个位置是可以“到达的”,到达这个位置不需要返回那么这个位置需要标记一下防止重复的走形成回路。
    visit[i][j] = true;
    for(int k = 0; k < 4; k++)
    {
        int x = i+tmp[k][0], y = j+tmp[k][1];
        dfs(x,y,cur+1);
    }
    //当递归程序返回到这个地方的时候要把这个位置重新标记为没有走过的位置。
    visit[i][j] = false;
}

int main()
{
    while(scanf("%d%d%d",&n,&m,&T) && (n||m||T))
    {
        for(int i = 1; i <= n; i++)
            scanf("%s",map[i]+1);
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                if(map[i][j] == 'S')
                {
                    start_x = i; start_y = j;
                }
                if(map[i][j] == 'D')
                {
                    end_x = i; end_y = j;
                }
            }
        }
        memset(visit,false,sizeof(visit));
        flag = false;
        dfs(start_x,start_y,0);
        if(flag)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
所以我们在写搜索算法的时候只需要考虑当我到达这个位置的时候是否需要返回就可以了。

你可能感兴趣的:(hdu 1010 Tempter of the Bone 解题报告)