过河卒(NOIP2002)

题目链接:过河卒
直接模拟?会T掉60分。
所以我们可以采用递推,怎么想到的?
因为卒子只能向下或向右走,所以走到一个点的方法数,等于走到它上面点的方法数加上走到它左边点的方法数,这样就可以地推了。
给代码:

#include
#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
using namespace std;
int main(){
    int n,m,a,b;
    scanf("%d%d%d%d",&n,&m,&a,&b);
    long long ans[n+1][m+1];           //1
    memset(ans,0,sizeof(ans));
    for(int i=0;i1;i++){              //2
        ans[0][i]=1;
        if((0==a&&i==b)||(0==a-1&&(i==b-2||i==b+2))||((0==a-2)&&(i==b-1||i==b+1))||((0==a+1)&&(i==b-2||i==b+2))||((0==a+2)&&(i==b-1||i==b+1))){   //5
                ans[0][i]=0;
                break;                   //6
        }
    }
    for(int i=1;i1;i++){              //3
        ans[i][0]=1;
        if((i==a&&0==b)||(i==a-1&&(0==b-2||0==b+2))||((i==a-2)&&(0==b-1||0==b+1))||((i==a+1)&&(0==b-2||0==b+2))||((i==a+2)&&(0==b-1||0==b+1))){
                ans[i][0]=0;
                break;
        }
    }
    for(int i=1;i1;i++){                 
        for(int j=1;j1;j++){
            ans[i][j]=ans[i-1][j]+ans[i][j-1];//4
            if((i==a&&j==b)||(i==a-1&&(j==b-2||j==b+2))||((i==a-2)&&(j==b-1||j==b+1))||((i==a+1)&&(j==b-2||j==b+2))||((i==a+2)&&(j==b-1||j==b+1))){
                ans[i][j]=0;
            }
        }
    }
    printf(LL,ans[n][m]);
    return 0;
}

一共提六处:
1处:ans用于保存答案
2、3处:初始化第一行、第一列为1
4处:递推
5处:这一大串就是判断是否在控制点。
6处:如果在,就把这一点清零,如果初始化的时候,那就直接退出,因为后面的点是走不到的。我就是因为初始化为判断控制点而丢了一部分的分。

你可能感兴趣的:(NOIP题解,NOIP详细(良心)题解,NOIP考前复习题目整理)