如圖,A 點有一個過河卒,須要走到目標 B 點。卒行走規則:能夠向下、或者向右。同時在棋盤上的任一點有一個對方的馬(如上圖的C點),該馬所在的點和全部跳躍一步可達的點稱爲對方馬的控制點。例如上圖 C 點上的馬能夠控制 9 個點(圖中的P1,P2 … P8 和 C)。卒不能經過對方馬的控制點。spa
棋盤用座標表示,A 點(0,0)、B 點(n,m)(n,m 爲不超過 20 的整數,並由鍵盤輸入),一樣馬的位置座標是須要給出的(約定: C不等於A,同時C不等於B)。如今要求你計算出卒從 A 點可以到達 B 點的路徑的條數。code
1<=n,m<=15blog
鍵盤輸入
B點的座標(n,m)以及對方馬的座標(X,Y){不用判錯}ip
屏幕輸出
一個整數(路徑的條數)。get
6 6 3 2it
17io
題目分析:class
要到達棋盤上的一個點,只能從左邊過來(咱們稱之爲左點)或是從上面過來(咱們稱之爲上點),因此根據加法原理,到達某一點的路徑數目,就等於到達其相鄰的上點和左點的路徑數目之和,所以咱們能夠使用逐列(或逐行)遞推的方法來求出從起點到終點的路徑數目。障礙點(馬的控制點)也徹底適用,只要將到達該點的路徑數目設置爲0便可。原理
用F[i][j]表示到達點(i,j)的路徑數目,g[i][j]表示點(i, j)有無障礙,g[i][j]=0表示無障礙,g[i][j]=1表示有障礙。
則,遞推關係式以下: F[i][j] = F[i-1][j] + F[i][j-1] //i>0且j>0且g[i][j]= 0
遞推邊界有4個:
F[i][j] = 0 //g[i][j] = 1
F[i][0] = F[i-1][0] //i > 0且g[i][0] = 0
F[0][j] = F[0][j-1] //j > 0且g[0][j] = 0
F[0][0] = 1
考慮到最大狀況下:n=20,m=20,路徑條數可能會超過231-1,因此要用高精度。gc
1 #include <stdio.h> 2 int main(int argc, char *argv[]) 3 { 4 int F[21][21]={0},G[21][21]={0}; 5 int i,j; 6 int n,m;//終點座標 7 int a,b;//馬的座標 8 9 scanf("%d%d",&n,&m);//輸入終點座標 10 scanf("%d%d",&a,&b);//輸入馬的座標 11 12 G[a][b]=1; 13 if(a-2>=0&&b-1>=0) {G[a-2][b-1]=1;} 14 if(a-2>=0&&b+1<=m) {G[a-2][b+1]=1;} 15 if(a+2<=n&&b-1>=0) {G[a+2][b-1]=1;} 16 if(a+2<=n&&b+1<=m) {G[a+2][b+1]=1;} 17 18 if(a-1>=0&&b-2>=0) {G[a-1][b-2]=1;} 19 if(a-1>=0&&b+2<=m) {G[a-1][b+2]=1;} 20 if(a+1<=n&&b-2>=0) {G[a+1][b-2]=1;} 21 if(a+1<=n&&b+2<=m) {G[a+1][b+2]=1;} 22 23 for(i=0;i<=n;i++)//初始化第一行和第一列,均爲1種走法。 24 { 25 if(G[i][0]==0){F[i][0]=1;} 26 else break; 27 } 28 for(i=0;i<=m;i++) 29 { 30 if(G[0][i]==0) {F[0][i]=1;} 31 else break; 32 } 33 for(i=1;i<=m;i++) 34 { 35 for(j=1;j<=n;j++) 36 { 37 if(G[j][i]!=1) 38 { 39 F[j][i]=F[j-1][i]+F[j][i-1]; 40 } 41 } 42 } 43 printf("%d",F[n][m]); 44 45 return 0; 46 }
另外一段比較優秀的代碼:
1 #include <stdio.h> 2 #include <stdlib.h> 3 int detX[8]={2,1,-1,-2,-2,-1,+1,+2}; 4 int detY[8]={1,2,+2,+1,-1,-2,-2,-1}; 5 int main() 6 { 7 int n,m,x,y,i,j; 8 long long F[25][25]={0}; 9 int xx,yy; 10 scanf("%d%d%d%d",&n,&m,&x,&y); 11 12 F[x][y]=-1; 13 for(i=0;i<8;i++) 14 { 15 xx=x+detX[i]; yy=y+detY[i]; 16 if(xx>=0&&xx<=n&&yy>=0&&yy<=m) F[xx][yy]=-1; 17 } 18 19 F[0][0]=1; 20 for(i=1;i<=n;i++)//初始化第0列 21 { 22 if(F[i][0]!=-1) F[i][0]=F[i-1][0]; 23 else F[i][0]=0; 24 } 25 for(j=1;j<=m;j++)//初始化第0行 26 { 27 if(F[0][j]!=-1) F[0][j]=F[0][j-1]; 28 else F[0][j]=0; 29 } 30 31 for(i=1;i<=n;i++) 32 { 33 for(j=1;j<=m;j++) 34 { 35 if(F[i][j]!=-1) F[i][j]=F[i][j-1]+F[i-1][j]; 36 else F[i][j]=0; 37 } 38 } 39 printf("%lld\n",F[n][m]); 40 return 0; 41 }