codevs 1010 過河卒

題目描述  Description

 如圖,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

輸入描述  Input Description

 鍵盤輸入
   B點的座標(n,m)以及對方馬的座標(X,Y){不用判錯}ip

輸出描述  Output Description

  屏幕輸出
    一個整數(路徑的條數)。get

樣例輸入  Sample Input

 6 6 3 2it

樣例輸出  Sample Output

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 }
相關文章
相關標籤/搜索