UVA 439 Knight Moves --DFS or BFS

简单搜索,我这里用的是dfs,由于棋盘只有8x8这么大,于是想到dfs应该可以过,后来由于边界的问题,TLE了,改了边界才AC。

这道题的收获就是知道了有些时候dfs没有特定的边界的时候要自己设置一个合适的边界。这题推导可知,任意两点之间马踩6步之内一定能够到达,6步之内还未搜到说明绝对不是最优结果,果断退出。所以这里的res开始时最小设定为6即可,随着设的res的增大,运行时间越来越多,因为深搜可以有很多的分支,不采取较小的边界的话,可能会浪费很多时间在无用的搜索上,所以需要如此剪枝。

反复提交验证发现,res设不同值的运行时间如下:

res = 6    102ms

res = 10  222ms

res = 20  429ms

res = 30  929ms     (过了30后极速增长)

res = 31  1692ms

res = 32  TLE !!!

代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

using namespace std;

#define N 9



int vis[N][N];

int res;

int dx[8] = {1,1,-1,-1,2,2,-2,-2};

int dy[8] = {2,-2,2,-2,1,-1,1,-1};



inline bool OK(int nx,int ny)

{

    if(nx >= 1 && nx <=8 && ny >= 1 && ny <= 8 && !vis[nx][ny])

        return true;

    return false;

}



void dfs(int sx,int sy,int tx,int ty,int cnt)

{

    if(cnt >= res)

        return;

    if(sx == tx && sy == ty && cnt < res)

    {

        res = cnt;

        return;

    }

    for(int i=0;i<8;i++)

    {

        int nx = sx + dx[i];

        int ny = sy + dy[i];

        if(!OK(nx,ny))

            continue;

        vis[nx][ny] = 1;

        dfs(nx,ny,tx,ty,cnt+1);

        vis[nx][ny] = 0;

    }

    return;

}



int main()

{

    char s1[4],s2[4];

    int sx,sy,tx,ty;

    while(scanf("%s%s",s1,s2)!=EOF)

    {

        sx = s1[0] - 'a' + 1;

        tx = s2[0] - 'a' + 1;

        sy = s1[1] - '0';

        ty = s2[1] - '0';

        memset(vis,0,sizeof(vis));

        vis[sx][sy] = 1;

        res = 6;   //·dfs边界,能取到正确的最小值最好,这里设为6或以上即可

        dfs(sx,sy,tx,ty,0);

        printf("To get from %s to %s takes %d knight moves.\n",s1,s2,res);

    }

    return 0;

}
View Code

 

你可能感兴趣的:(move)