简单搜索,我这里用的是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[] = {,,-,-,,,-,-};
int dy[] = {,-,,-,,-,,-}; inline bool OK(int nx,int ny)
{
if(nx >= && nx <= && ny >= && ny <= && !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=;i<;i++)
{
int nx = sx + dx[i];
int ny = sy + dy[i];
if(!OK(nx,ny))
continue;
vis[nx][ny] = ;
dfs(nx,ny,tx,ty,cnt+);
vis[nx][ny] = ;
}
return;
} int main()
{
char s1[],s2[];
int sx,sy,tx,ty;
while(scanf("%s%s",s1,s2)!=EOF)
{
sx = s1[] - 'a' + ;
tx = s2[] - 'a' + ;
sy = s1[] - '';
ty = s2[] - '';
memset(vis,,sizeof(vis));
vis[sx][sy] = ;
res = ; //·dfs边界,能取到正确的最小值最好,这里设为6或以上即可
dfs(sx,sy,tx,ty,);
printf("To get from %s to %s takes %d knight moves.\n",s1,s2,res);
}
return ;
}