题目链接:过河卒

直接模拟?会T掉60分。

所以我们可以采用递推,怎么想到的?

因为卒子只能向下或向右走,所以走到一个点的方法数,等于走到它上面点的方法数加上走到它左边点的方法数,这样就可以地推了。

给代码:

#include<bits/stdc++.h>
#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;i<m+1;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;i<n+1;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;i<n+1;i++){
for(int j=1;j<m+1;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处:如果在,就把这一点清零,如果初始化的时候,那就直接退出,因为后面的点是走不到的。我就是因为初始化为判断控制点而丢了一部分的分。

05-11 14:00