1. 程式人生 > >洛谷 過河卒 p1002 題解

洛谷 過河卒 p1002 題解

其實這道題如果你會遞推,搞清楚問題的本質就很簡單了

首先我們要知道加法原理,加法原理是什麼呢?舉個栗子:如果我們去上海只可以坐火車,坐飛機。而火車有n班次,飛機有m班次。那麼總共去上海就有(n+m)種方式。

之後,我們就可以推出這個題目的遞推表示式:

(ps:我們用f(x)(y)的形式來表示到達點(x,y)的步數。而且設g(n)(m)=1為馬的的位置,那麼馬可能走到的位置(包括馬的初始位置)為:)

> g[n][m];
    g[n-2][m+1];
    g[n-1][m+2];
    g[n-2][m-1];
    g[n-1][m-2];
    g[n+1][m-2];
    g[n+2][m-1];
    g[n+2][m+1];
    g[n+1][m+2]; 

1.如果終點在馬的控制點(即馬能走到得位置),毫無疑問步數為02.如果馬的終點不在馬的控制點上,那麼步數就是所有上一步的步數之和,即 f(x)(y)=f(x-1)(y)+f(x)(y-1)(x,y為座標)。但此處還有兩種特殊情況:

  • 一種是剛好x等於0,那麼f(x)(y)=f(x)(y-1)(因為馬只能向y軸方向移動,所以上一個位置只能為(x,y-1) )

  • 一種是剛好y等於0,那麼f(x)(y)=f(x-1)(y)(因為馬只能向x軸方向移動,所以上一個位置只能為(x-1,y))

3.最後我們要設定起點f(0)(0)=1;

所以綜上,我們可以寫出程式

#include <iostream>
#include <cstdio>

using namespace std;

long long map[25][25];
int g[25][25];//g[i][j]==1為馬的控制點 

int main(){
    int a,b,n,m;//(a,b)為b的座標,(n,m)為馬的座標
    cin>>a>>b>>n>>m;
    //馬的控制點
    g[n][m]=1;
    g[n-2][m+1]=1;
    g[n-1][m+2]=1;
    g[n-2][m-1]=1;
    g[n-1][m-2]=1;
    g[n+1][m-2]=1;
    g[n+2][m-1]=1;
    g[n+2][m+1]=1;
    g[n+1][m+2]=1; 

    for (int i=0;i<=a;i++){

        for (int j=0;j<=b;j++){

            if (g[i][j]==1){

                map[i][j]=0;

            }else{          //如果不在馬的控制點上 

                if (i==0&&j==0){

                    map[i][j]=1;//如果在起點
                    continue;//這個很重要,因為判斷出一種結果後就要判斷下一位置了

                    } 
                if (i==0) {

                    map[i][j]=map[i][j-1];
                    continue;

                }
                if (j==0){

                    map[i][j]=map[i-1][j]; 
                    continue;

                }

                map[i][j]=map[i][j-1]+map[i-1][j]; 

            } 

        }

    }

    cout<<map[a][b];

    return 0;

}