引用1:https://blog.csdn.net/wuhao1995/article/details/51242669
引用2:https://blog.csdn.net/yuyanggo/article/details/47657397
来源:NOIP1997 普及组
#include<bits/stdc++.h>
#define maxn 60
#define l 10000000000
using namespace std;
struct number{
long long d1,d2; //存储方案的后20位
}f[maxn][maxn];
int n,m;
int flag[maxn][maxn]; //障碍标记
void start(){
long long s;
f[1][1].d1=1;f[1][1].d2=0;
for(int k=3;k<=m+n;k++){
for(int i=1;i<=n;i++){
if(k-i>=1&&k-i<=m&&!flag[i][k-i]){
int j=k-i;
if(j-1>=1){
f[i][j]=f[i][j-1];
} //将前一项给后一项赋值
if(i-1>=1){ //将前一项的值相加
s=f[i][j].d1+f[i-1][j].d1;
f[i][j].d1=s%l;
f[i][j].d2=(f[i-1][j].d2+f[i][j].d2+s/l)%l;
}//养成良好习惯,加大括号
}
}
}
if(f[n][m].d2==0) printf("%I64d\n",f[n][m].d1);
else printf("%I64d%010I64d\n",f[n][m].d2,f[n][m].d1); //对前十位不足的用0填充
}
int main(){
int x1,x2,y1,y2;
scanf("%d%d",&n,&m);
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(x1>x2){
swap(x1,x2); //对障碍的 起始点进行转换
}
if(y1>y2){
swap(y1,y2);
}
for(int i=x1;i<=x2;i++){
for(int j=y1;j<=y2;j++){
flag[i][j]=1; //对障碍进行标记
}
}
start();
return 0;
}
题后感:很难,难的不像二维数组,不太容易看得懂,但对于初学者是道很好地锻炼题,适合长时间思考。