[重返NOIP]动态规划1——NOIP2002普及组 过河卒
题目描述 棋盘上 $A$ 点有一个过河卒,需要走到目标 $B$ 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 $C$ 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。 棋盘用坐标表示,$A$ 点 $(0, 0)$、$B$ 点 $(n, m)$,同样马的位置坐标是需要给出的。 现在要求你计算出卒从 $A$ 点能够到达 $B$ 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。 输入格式 一行四个正整数,分别表示 $B$ 点坐标和马的坐标。 输出格式 一个整数,表示所有的路径条数。 样例 #1 样例输入 #1 6 6 3 3 样例输出 #1 6 提示 对于 $100 \%$ 的数据,$1 \le n, m \le 20$,$0 \le$ 马的坐标 $\le 20$。 【题目来源】 NOIP 2002 普及组第四题 思路 很简答,结合递归的想法,先把所有格子赋值为0,被马挡的格子标为2,只要碰到就return相应值就行 代码 #include<stdio.h> int bx,by,mx,my; int f(int **pan1,int bx1,int by1,int zx1,int zy1){ if(zy1+1<=by1&&zx1+1<=bx1){ if(pan1[zy1+1][zx1]==0||pan1[zy1][zx1+1]==0) return f(pan1,bx1,by1,zx1+1,zy1)+f(pan1,bx1,by1,zx1,zy1+1); else return 0; }else if(zy1==by1&&zx1+1<=bx1){ return f(pan1,bx1,by1,zx1,zy1+1); }else if(zy1+1<=by1&&zx1==bx1){ return f(pan1,bx1,by1,zx1+1,zy1); }else if(zy1==by1&&zx1==bx1){ return 1; }else return 0; } int main(){ scanf("%d %d %d %d",bx,by,mx,my); int zx=0,zy=0,pan[by+1][bx+1]; for(int i=0;i<=by;i++){ for(int j=0;j<=bx;j++){ pan[i][j]=0; } } pan[my][mx]=1; if(mx+1<=bx&&my+2<=my) pan[my+2][mx+1]=1; if(mx-1<=bx&&my+2<=my) pan[my+2][mx-1]=1; if(mx-2<=bx&&my+1<=my) pan[my+1][mx-2]=1; if(mx+2<=bx&&my+1<=my) pan[my+1][mx+2]=1; if(mx+1<=bx&&my-2<=my) pan[my-2][mx+1]=1; if(mx-1<=bx&&my-2<=my) pan[my-2][mx-1]=1; if(mx-2<=bx&&my-1<=my) pan[my-1][mx-2]=1; if(mx+2<=bx&&my-1<=my) pan[my-1][mx+2]=1; printf("%d",f(pan,bx,by,zx,zy)); } (由于尚未搞清的原因,上述代码还无法运行,具体错误也还没发现) ...