题目链接:http://poj.org/problem?id=1915
题目大意:
你的任务是编写一个程序来计算的骑士达到从另一个位置所要移动的最少步数,这样你才有机会比Somurolov快。 也许人们不熟悉的国际象棋,骑士行动可能在如图1所示。 输入 首先在第一个行,输入n,表示有n种的情况。 接下来是n方案。每个方案包括三行。第一行指定一个棋盘边长L(4<=L<= 300)。整个棋盘的尺寸L *L.第二和第三行包含整数对(0,...,L - 1)*(0,...,L - 1)指定骑士开始和结束位置。整数对由一个空白分隔开。 输出 对于每个输入你要计算骑士的行动,有必要从起点移动到终点最少步数的情况。如果起点和终点都是平等的,距离是零。
解题思路:
广度搜索,从起始点开始,每次向8个方向探索。直到到达终点。
AC代码如下:
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;
public class Main{
static LinkedList<Knight> list=new LinkedList<Knight>();
static int visited[][]=new int[305][305];
//规定的8个方向
static int direction[][]={{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1},{2,1},{1,2}};
static int x1,x2,y1,y2,n;
static boolean check(int x,int y){
if(x<0||x>=n||y<0||y>=n){
return false;
}
return true;
}
static int Bfs(){
Knight knight,kn;
while(!list.isEmpty()){
knight=list.removeFirst();
if(knight.x==x2&&knight.y==y2){
return knight.step;
}
for(int i=0;i<direction.length;i++){
kn=new Knight(knight.x+direction[i][0],knight.y+direction[i][1],knight.step);
if(!check(kn.x,kn.y)||visited[kn.x][kn.y]==1){
continue;
}
visited[kn.x][kn.y]=1;
kn.step++;
list.add(kn);
}
}
return -1;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int t=sc.nextInt();
while(t-->0){
list.clear();
n=sc.nextInt();
x1=sc.nextInt();
y1=sc.nextInt();
x2=sc.nextInt();
y2=sc.nextInt();
for(int i=0;i<visited.length;i++){
Arrays.fill(visited[i],0);
}
list.add(new Knight(x1,y1,0));
visited[x1][y1]=1;
System.out.println(Bfs());
}
}
}
}
class Knight{
int x;
int y;
int step;
public Knight(int x, int y, int step) {
this.x = x;
this.y = y;
this.step = step;
}
}