1. 程式人生 > >過河卒(Noip2002)

過河卒(Noip2002)

【題目描述】
棋盤上A點有一個過河卒,需要走到目標B點。卒行走的規則:可以向下、或者向右。同時在棋盤上的某一點有一個對方的馬(如C點),該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點,如圖3-1中的C點和P1,……,P8,卒不能通過對方馬的控制點。棋盤用座標表示,A點(0,0)、B點(n, m) (n,m為不超過20的整數),同樣馬的位置座標是需要給出的,C≠A且C≠B。現在要求你計算出卒從A點能夠到達B點的路徑的條數。



【輸入】
給出n、m和C點的座標。

【輸出】
從A點能夠到達B點的路徑的條數。

【輸入樣例】
8 6 0 4
【輸出樣例】
1617
#include <bits/stdc++.h>

using
namespace std; int long long f[25][25],d[25][25]; void aa(int x,int y) //這個函式用來判斷馬的控制點是否會越界 { int i,j,k; if(x<0 || x>20 || y<0 || y>20) return; else d[x][y]=1; } int main() { int n,m,x,y; int i,j; cin>>n>>m>>x>>y; aa(x-1,y+2); aa(x
+1,y+2); aa(x-2,y+1); aa(x+2,y+1); aa(x-2,y-1); aa(x+2,y-1); aa(x-1,y-2); aa(x+1,y-2); aa(x,y); f[0][0]=1; //一開始什麼都不走也是1種走法,有種遞推的邊界的感覺
for(i=0;i<=n;i++) //從行列迴圈遍歷所有的走法 for(j=0;j<=m;j++) { if(d[i][j]==0&&i>0&&j>0) //若此點不是馬的控制點而且i,j存在的情況 { f[i][j]
=f[i-1][j]+f[i][j-1]; } else if(d[i][j]==1) //這是此點是馬的控制點的情況 f[i][j]=0; else if(i>0&&d[i][0]==0) //這是y=0並且此點不是馬的控制點的情況就只有一種走法 f[i][0]=f[i-1][0]; else if(j>0&&d[0][j]==0) //同上 f[0][j]=f[0][j-1]; } cout<<f[n][m]<<endl; return 0; }

根據加法原理,到達某一點的路徑數目,等於到達其相鄰的上點和坐點的路徑數目之和。
所以得到遞推公式:
f[i][j]=f[i-1][j]+f[i][j-1]
別忘了用long long