題目描述 Description
如圖,A 點有一個過河卒,需要走到目標 B 點。卒行走規則:可以向下、或者向右。同時在棋盤上的任一點有一個對方的馬(如上圖的C點),該馬所在的點和所有跳躍一步可達的點稱爲對方馬的控制點。例如上圖 C 點上的馬可以控制 9 個點(圖中的P1,P2 … P8 和 C)。卒不能通過對方馬的控制點。
棋盤用座標表示,A 點(0,0)、B 點(n,m)(n,m 爲不超過 20 的整數,並由鍵盤輸入),同樣馬的位置座標是需要給出的(約定: C不等於A,同時C不等於B)。現在要求你計算出卒從 A 點能夠到達 B 點的路徑的條數。
1<=n,m<=15
輸入描述 Input Description
鍵盤輸入
B點的座標(n,m)以及對方馬的座標(X,Y){不用判錯}
輸出描述 Output Description
屏幕輸出
一個整數(路徑的條數)。
樣例輸入 Sample Input
6 6 3 2
樣例輸出 Sample Output
17
數據範圍及提示 Data Size & Hint
如描述
分析:
DFS,通過移動判斷不在馬的攻擊範圍即可,一直到達目標點B,假設馬的位置座標爲(x,y),則馬的其他八個可攻擊範圍的座標分別爲:(x+1,y-2), (x+1,y+2),(x+2,y-1),(x+2,y+1),(x-1,y-2),(x-1,y+2),(x-2,y-1)(x-2,y+1)。
代碼如下:
public class DFSTest {
private static Integer ans = 0;
//馬可攻擊範圍點
private static final Integer[][] horseXY = {{0,0},{1,-2},{1,2},{2,-1},{2,1},{-1,-2},{-1,2},{-2,-1},{-2,1}};
//targetXY[0][0],targetXY[0][1]目標點B座標,targetXY[1][0],targetXY[1][1]馬C座標
private static final Integer[][] targetXY = new Integer[2][2];
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入B和C座標:");
String[] strs = scanner.nextLine().trim().split(" ");
targetXY[0][0] = Integer.parseInt(strs[0]);
targetXY[0][1] = Integer.parseInt(strs[1]);
targetXY[1][0] = Integer.parseInt(strs[2]);
targetXY[1][1] = Integer.parseInt(strs[3]);
DFSSearch(0,0);
System.out.println(ans);
}
private static void DFSSearch(int x, int y){
//到達目標B點
if (x == targetXY[0][0] && y == targetXY[0][1]){
ans++;
return;
}
//超出座標範圍
if(x < 0 || x > targetXY[0][0] || y < 0 || y > targetXY[0][1]){
return;
}
//馬C點的可攻擊點
for (int i = 0; i < 9; i++){
int hx = targetXY[1][0] + horseXY[i][0];
int hy = targetXY[1][1] + horseXY[i][1];
if (x == hx && y == hy){
return;
}
}
DFSSearch(x+1, y);
DFSSearch(x, y+1);
}
}