題目描述
棋盤上 a 點有乙個過河卒,需要走到目標 b 點。卒行走的規則:可以向下、或者向右。同時在棋盤上 c 點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為「馬攔過河卒」。
棋盤用座標表示,a 點 (0, 0)、b 點 (n, m),同樣馬的位置座標是需要給出的。
現在要求你計算出卒從 a 點能夠到達 b 點的路徑的條數,假設馬的位置是固定不動的,並不是卒走一步馬走一步。
輸入格式
一行四個正整數,分別表示 b 點座標和馬的座標。
輸出格式
乙個整數,表示所有的路徑條數。
輸入輸出樣例:
輸入 #16 6 3 3
輸出 #1
6
#include
#include
#include
#include
using
namespace std;
intmain()
;//21是選擇棋盤最大的大小即可,超過20用int不行,只能用long long了
bool block[21]
[21]=
;//利用額外的空間標記不能走的區域,用bool比int節省空間
int tettior[18]
=;//協助標記馬的控制範圍
cin >> x >> y >> x1 >> y1;
//(x,y)是終點座標,(x1,y1)是馬的座標
for(
int i =
1; i <
18; i+=2
) a[0]
[0]=
1;//卒子開始站的位置,馬不可能站在同一位置,故到(0,0)一定有1條路徑
for(
int i =
0; i <= x; i++
)else
if(j >0)
}}} cout << a[x]
[y];
//輸出答案即可
return0;
}
這道題很多邊界條件,除錯了很久都沒能ac,不少陣列越界的條件一開始都沒有想到,耗費了很多時間去單步除錯。
思路:棋盤如下
a 0 0 0 0 0 0其中每個點的值代表的是當前這個點會有幾條路徑用過這個點(路徑指的是從a到b的路徑),用的是案例(6 6 3 3)的棋盤。0 0 x 0 x 0 0
0 x 0 0 0 x 0
0 0 0 m 0 0 0
0 x 0 0 0 x 0
0 0 x 0 x 0 0
0 0 0 0 0 0 b
1 1 1 1 1 1 1每乙個格仔都是由上方或者左方的格仔走過來的,可以得到乙個式子:1 2 x 1 x 1 2
1 x 0 1 1 x 2
1 1 1 m 1 1 3
1 x 1 1 0 x 3
1 1 x 1 x 0 3
1 2 2 3 3 3 6
不斷遞推,往終點逼近
最終a[x][y]就是答案了。..
...由於我們只需要最終的a[x][y],額外空間a陣列可以由二維變成一維陣列,較大的節省空間。即上面的a[21][21]只需開a[21]即可
將上面好理解的轉移公式變成
先要memeset(f , 0 , sizeof(f));將f陣列都置0
f[0][0] = 1;
即可等式右邊的f[ i ]理解成上方的格仔 , f[i-1]理解成左方的格仔。
等式左邊的f [ i ] 理解成即將接受更新資料的當前格仔
ok,大致思路如上,
馬攔過河卒
問題描述 棋盤上a 點有乙個過河卒,需要走到目標 b點。卒行走的規則 可以向下 或者向右。同時在棋盤上 c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為 馬攔過河卒 棋盤用座標表示,a 點 0,0 b 點 n,m n,m為不超過 15的整數 同樣馬的位置座標是需要...
馬攔過河卒
如圖,a點有乙個過河卒,需要走到目標 b點。卒行走規則 可以向下 或者向右。同時在棋盤上的任一點有乙個對方的馬 如上圖的c點 該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。例如上圖 c點上的馬可以控制 9個點 圖中的p1,p2 p8和 c 卒不能通過對方馬的控制點。棋盤用座標表示,a點 0,...
馬攔過河卒
problem description 棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則 可以向下 或者向右。同時在棋盤上c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為 馬攔過河卒 棋盤用座標表示,a點 0,0 b點 n,m n,m為不超過15的整數 同樣...