problem
棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則:可以向下、或者向右。同時在棋盤上c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為「馬攔過河卒」。
棋盤用座標表示,a點(0, 0)、b點(n, m)(n, m為不超過15的整數),同樣馬的位置座標是需要給出的。現在要求你計算出卒從a點能夠到達b點的路徑的條數,假設馬的位置是固定不動的,並不是卒走一步馬走一步。
輸入描述 input description
一行四個資料,分別表示b點座標和馬的座標。
輸出描述 output description
乙個資料,表示所有的路徑條數。
樣例輸入 sample input
6 6 3 3
樣例輸出 sample output
思路
如果用搜尋的方法,每乙個點都有向下向左兩種方案。2的24次方是1e8級別的,所以這種方法很不好。
如果沒有那些卒,從左上角到右下角是乙個經典的組合問題,方案數為c(n+m,n)/c(n+m,m)。
現在問題是在表中會有一些障礙,經過這些障礙的方案都將捨去,這時候我們用遞推的思想去解決。實際上,上面的組合數公式也是遞推得到的結果(組合數本身也有遞推方程):
由於卒只能向下或者向右走,那麼想要到達棋盤上的乙個點,有兩種方式:從左邊的格仔過來,或者從上邊的格仔過來。所以,過河卒到達某點的路徑數目等於到達與其相鄰的左邊點和上邊點的路徑數目和。我們用f(i,j) 來表示到達點 (i,j) 的路徑數目。所以遞推式為:f(i,j)=f(i-1,j)+f(i,j-1)。根據遞推式發現,可以用逐行或逐列的遞推方法求出從起點到終點的路徑數目。對於邊界條件,因為(0,0)是卒的起始位置,那麼f(0,0) = 1。
這樣先標記好障礙點,那麼障礙點這一定fi,j一定等於0,最終遞推得到的fn,m就是所求方案數了。
#includeusing namespace std;typedef long long ll;
const int maxn=30;
ll ans[maxn][maxn];
int vis[maxn][maxn];
int dir1[8]=;
int dir2[8]=;
int main()
}ans[0][0]=1;
for(int i=0;i<=n;++i)
if(j)}}
cout
}
馬踏過河卒
馬踏過河卒 problem description 棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則 可以向下 或者向右。同時在棋盤上c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為 馬攔過河卒 棋盤用座標表示,a點 0,0 b點 n,m n,m為不超過15...
馬踏過河卒
棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則 可以向下 或者向右。同時在棋盤上c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為 馬攔過河卒 棋盤用座標表示,a點 0,0 b點 n,m n,m為不超過15的整數 同樣馬的位置座標是需要給出的。現在要求你計算...
馬攔過河卒問題 (遞推解法)
過河卒 noip2002初中組複賽第四題 問題描述 棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則 可以向下或向右。同時在棋盤上的任一點有乙個對方的馬 如圖中的c點 該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。例如圖中c點上的馬可以控制9個點。卒不能走到對方馬的控制點。棋盤用座標表...