棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上的某一点有一个对方的马(如C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点,如图3-1中的C点和P1,……,P8,卒不能通过对方马的控制点。棋盘用坐标表示,A点(0,0)、B点(n, m) (n,m为不超过20的整数),同样马的位置坐标是需要给出的,C≠A且C≠B。现在要求你计算出卒从A点能够到达B点的路径的条数。
给出n、m和C点的坐标。
从A点能够到达B点的路径的条数。
8 6 0 4
1617
书上说要用高精度,但是其实long long就完全够了
(用long long 保存结果的写法)
#include
using namespace std;
int main () {
long long ans[21][21]={1};//ans[i][j]表示从(0,0)到(i,j)的方法数
bool f[21][21]={0};//保存是否为马的控制点的,是为1 否则为0
int direction [8][2]={{-2,-1},{-2,1},{2,-1},{2,1},{-1,-2},{1,-2},{-1,2},{1,2}};//跳马的方向
int n,m,x,y,i,j;
scanf("%d%d%d%d",&n,&m,&x,&y);
f[x][y]=1;
for (i=0;i<8;i++) {//初始化马的控制点
int tx=x+direction[i][0],ty=y+direction[i][1];
if((tx<=n&&tx>=0)&&(ty<=m&&ty>=0)) f[tx][ty]=1;
}
for (i=1;i<=n;i++) if(!f[i][0]) ans[i][0]=ans[i-1][0];
for (i=1;i<=m;i++) if(!f[0][i]) ans[0][i]=ans[0][i-1];//初始化边缘情况
for (i=1;i<=n;i++) {
for (j=1;j<=m;j++) {
if(!f[i][j])ans[i][j]+=ans[i-1][j]+ans[i][j-1];
}
}
printf("%lld",ans[n][m]);
return 0;
}
(用高精度的办法)
#include
#include
using namespace std;
struct bignum {
int num[101];
} ans[21][21];
void bignumadd (bignum &,bignum &);//高精度加法,结果保存在前一个高精度数中
void bignumprint (bignum);//高精度数输出
int main () {
bool f[21][21]={0};
int direction [8][2]={{-2,-1},{-2,1},{2,-1},{2,1},{-1,-2},{1,-2},{-1,2},{1,2}};
int n,m,x,y,i,j;
scanf("%d%d%d%d",&n,&m,&x,&y);
f[x][y]=1;
ans[0][0].num[1]=1;
for (i=0;i<8;i++) {
int temx=x+direction[i][0],temy=y+direction[i][1];
if((temx>=0&&temx<=n)&&(temy>=0&&temy<=m)) f[temx][temy]=1;
}
for (i=0;i<=n;i++) {
for (j=0;j<=m;j++) {
if(i!=0&&j!=0) {
memset(ans[i][j].num,0,sizeof(ans[i][j].num));
}
ans[i][j].num[0]=1;
if(i==0&&j>0&&!f[i][j]) ans[0][j].num[1]=ans[0][j-1].num[1];
else if(j==0&&i>0&&!f[i][j]) ans[i][0].num[1]=ans[i-1][0].num[1];
}
}
for (i=1;i<=n;i++) {
for (j=1;j<=m;j++) {
if(!f[i][j]) {
bignumadd(ans[i][j],ans[i-1][j]);
bignumadd(ans[i][j],ans[i][j-1]);
}
}
}
bignumprint(ans[n][m]);
return 0;
}
void bignumadd (bignum &a,bignum &b) {
int max=a.num[0]>b.num[0]?a.num[0]:b.num[0];
int i;
for (i=1;i<=max;i++) {
a.num[i]+=b.num[i];
if(a.num[i]>9) {
a.num[i+1]++;
a.num[i]-=10;
}
}
a.num[0]=max+1;
if (a.num[a.num[0]]==0) a.num[0]--;
}
void bignumprint (bignum a) {
for (int i=a.num[0];i>0;i--) {
printf("%d",a.num[i]);
}
}