【题目链接】click here~~
【题目大意】类型于中国象棋里面“马”的走法,给你两个坐标,一个初始坐标,一个最终坐标,在保证有解的情况下最小的步数
【思路】BFS的话,直接模拟,因为棋盘比较小
(1)BFS +队列
代码:(3ms)
#include <bits/stdc++.h>
using namespace std;
int dir8[8][2]= {{1,2},{2,1},{-1,2},{-2,1},{1,-2},{2,-1},{-1,-2},{-2,-1}};
bool vis[10][10]; /// Memory search
struct node{
int x,y,step; /// Coordinate and step
} pre,last;
bool ok(int dx,int dy){
if(dx>=1&&dx<=8&&dy>=1&&dy<=8) return true;
return false;
}
int bfs(node pre,node last){
queue <node >val;
while(!val.empty()) val.pop();
node top,b;
vis[pre.x][pre.y]=true;
val.push(pre);
while(!val.empty())
{
top=val.front();
val.pop();
if(top.x==last.x&&top.y==last.y) return top.step;
for(int i=0; i<8; ++i){
b.x=top.x+dir8[i][0];
b.y=top.y+dir8[i][1];
if(ok(b.x,b.y)&&!vis[b.x][b.y]){
vis[b.x][b.y]=true;
b.step=top.step+1;
val.push(b);
}
}
}
return 0;
}
char c1[5],c2[5];
int res;
int main(){
while(~scanf("%s %s",c1,c2)){
memset(vis,0,sizeof(vis));
pre.x=c1[0]-'a'+1;pre.y=c1[1]-'0';pre.step=0;
last.x=c2[0]-'a'+1;last.y=c2[1]-'0';last.step=0;
res=bfs(pre,last);
printf("To get from %s to %s takes %d knight moves.\n",c1,c2,res);
} return 0;
}
/*
Sample Input
e2 e4
a1 b2
b2 c3
a1 h8
a1 h7
h8 a1
b1 c3
f6 f6
Sample Output
To get from e2 to e4 takes 2 knight moves.
To get from a1 to b2 takes 4 knight moves.
To get from b2 to c3 takes 2 knight moves.
To get from a1 to h8 takes 6 knight moves.
To get from a1 to h7 takes 5 knight moves.
To get from h8 to a1 takes 6 knight moves.
To get from b1 to c3 takes 1 knight moves.
To get from f6 to f6 takes 0 knight moves.
*/
(2)DFS:
收获:有些时候DFS没有特定的边界,需要自己设置一个合适的边界。这题推导可知,任意两点之间马踩6步之内一定能够到达,6步之内还未搜到说明绝对不是最优结果,果断退出。所以这里的res开始时最小设定为6即可,随着设的res的增大,运行时间越来越多,因为深搜可以有很多的分支,不采取较小的边界的话,可能会浪费很多时间在无用的搜索上,所以需要剪枝。
res设不同值的运行时间如下:
res = 6 39ms
........
res = 32 TLE !!!
代码:(39ms)
#include <bits/stdc++.h>
using namespace std;
int dir8[8][2]= {{1,2},{2,1},{-1,2},{-2,1},{1,-2},{2,-1},{-1,-2},{-2,-1}};
bool vis[10][10];
int q;
inline bool ok(int dx,int dy){
if(dx>=1&&dx<=8&&dy>=1&&dy<=8) return true;
return false;
}
void dfs(int px,int py,int lx,int ly,int deep){
if(deep>=q) return ;
if(px==lx&&py==ly&&deep<q){
q=deep;
return ;
}
for(int i=0; i<8; ++i){
int dx=px+dir8[i][0];
int dy=py+dir8[i][1];
if(ok(dx,dy)&&!vis[dx][dy]){
vis[dx][dy]=1;
dfs(dx,dy,lx,ly,deep+1);
vis[dx][dy]=0;
}
}
return ;
}
char c1[5],c2[5];
int px,py,lx,ly;
int main()
{
while(~scanf("%s %s",c1,c2)){
px=c1[0]-'a'+1;py=c1[1]-'0';
lx=c2[0]-'a'+1;ly=c2[1]-'0';
memset(vis,0,sizeof(vis));
q=6;
vis[px][py]=1;
dfs(px,py,lx,ly,0);
printf("To get from %s to %s takes %d knight moves.\n",c1,c2,q);
}
return 0;
}