信息学奥赛一本通c语言,[信息学奥赛一本通-T1314]过河卒-题解(C语言代码)

该博客探讨了两种方法解决棋盘上马走日字路径计数的问题。首先,介绍了递归方法,虽然时间复杂度较高但能在IDE中实现。接着,提出动态规划解决方案,重点在于初始化状态的设定,并通过二维数组dp记录路径。动态规划降低了时间复杂度,提高了效率。最终,代码展示了如何计算从起点到终点的不同路径数量。
摘要由CSDN通过智能技术生成

递归方法:----时间复杂度太高,但是ide中可以实现

int count=0;//总次数

int flag[30][30]={{0},{0}};//标记是否有马

int judge(int x,int y,int n,int m)

{

if(x>=0&&x<=n&&y>=0&&y<=m)

{

return 1;

}

return 0;

}

void perm(int a,int b,int n,int m,int flag[][30])//由(a,b)->(n,m)

{

if(a==n&&b==m){count++;return ;}//出口

else

{

if((b+1)<=m&&flag[a][b+1]==0)

{

perm(a,b+1,n,m,flag);

}

if(a+1<=n&&flag[a+1][b]==0)

{

perm(a+1,b,n,m,flag);

}

}

return ;

}

int main()

{

int n,m,x,y;

scanf("%d%d%d%d",&n,&m,&x,&y);

if(judge(x,y,n,m)==1){flag[x][y]=1;}

if(judge(x-1,y-2,n,m)==1){flag[x-1][y-2]=1;}

if(judge(x+1,y-2,n,m)==1){flag[x+1][y-2]=1;}

if(judge(x-2,y-1,n,m)==1){flag[x-2][y-1]=1;}

if(judge(x-2,y+1,n,m)==1){flag[x-2][y+1]=1;}

if(judge(x-1,y+2,n,m)==1){flag[x-1][y+2]=1;}

if(judge(x+1,y+2,n,m)==1){flag[x+1][y+2]=1;}

if(judge(x+2,y-1,n,m)==1){flag[x+2][y-1]=1;}

if(judge(x+2,y+1,n,m)==1){flag[x+2][y+1]=1;}

perm(0,0,n,m,flag);

printf("%d",count);

return 0;

}

法2:动态规划:===注意,此时初始化问题是关键,dp[0][i]的情况遇到第一个马之前都是为1种走法,遇到第一个之后,后面的都是为0;

int count=0;//总次数

int flag[30][30]={{0},{0}};//标记是否有马

int judge(int x,int y,int n,int m)

{

if(x>=0&&x<=n&&y>=0&&y<=m)

{

return 1;

}

return 0;

}

int main()

{

int n,m,x,y;

scanf("%d%d%d%d",&n,&m,&x,&y);

if(judge(x,y,n,m)==1){flag[x][y]=1;}

if(judge(x-1,y-2,n,m)==1){flag[x-1][y-2]=1;}

if(judge(x+1,y-2,n,m)==1){flag[x+1][y-2]=1;}

if(judge(x-2,y-1,n,m)==1){flag[x-2][y-1]=1;}

if(judge(x-2,y+1,n,m)==1){flag[x-2][y+1]=1;}

if(judge(x-1,y+2,n,m)==1){flag[x-1][y+2]=1;}

if(judge(x+1,y+2,n,m)==1){flag[x+1][y+2]=1;}

if(judge(x+2,y-1,n,m)==1){flag[x+2][y-1]=1;}

if(judge(x+2,y+1,n,m)==1){flag[x+2][y+1]=1;}

int dp[n+1][m+1];

for(int i=0;i<=n;i++)//初始化,有马就是0,没马就是1

{

for(int j=0;j<=m;j++)

{

dp[i][j]=0;

}

}

for(int i=0;i<=m;i++)

{

if(flag[0][i]==0){dp[0][i]=1;}

else break;

}

for(int i=0;i<=n;i++)

{

if(flag[i][0]==0){dp[i][0]=1;}

else break;

}

for(int i=1;i<=n;i++)

{

for(int j=1;j<=m;j++)

{

if(flag[i][j]==0)

{

dp[i][j]=dp[i-1][j]+dp[i][j-1];

}

}

}

printf("%d",dp[n][m]);

return 0;

}

0.0分

2 人评分

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值