题目描述
乐乐有一个棋盘,共有m行n列,一只棋子从左上角开始,向右下角移动,每次只能向下或向右移动一次。然而这个棋盘中有一些障碍物,这些障碍物使得这个棋子不能进入这些格子,问这个棋子从左上角到达右下角共有多少种不同的移法?如果到达不了,则输出0。
输入
两个整数m,n,0<m,n≤100。
后面有m行,每行有n个数(0或1),如果是1,则表示这个方格中有障碍物。
输出
求得的方案数。
样例输入 复制
样例1
4 5
0 0 1 0 0
0 1 0 0 0
0 0 0 0 0
0 1 0 0 0
样例2
3 3
1 0 1
1 1 0
0 0 0
样例输出 复制
样例1
3
样例2
0
参考代码不超时:
#include<cstdio>
#include<iostream>
using namespace std;
int m,n,ans;
int a[101][101];
int bz[101][101][101];
void add(int g,int k)
{
int l=max(bz[g-1][k][0],bz[g][k-1][0]);
for(int i=1;i<=l;i++)
{
bz[g][k][i]=bz[g][k][i]+bz[g-1][k][i]+bz[g][k-1][i];
bz[g][k][i+1]=bz[g][k][i]/10;
bz[g][k][i]%=10;
}
if(bz[g][k][l+1]>0) bz[g][k][0]=l+1;
else bz[g][k][0]=l;
}
int main()
{
int flag=false;
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
for(int j=1;j<=n;j++)
bz[1][j][0]=1;
for(int i=1;i<=m;i++)
bz[i][1][0]=1;
if(a[1][1]==1||a[m][n]==1)
{
printf("0");
return 0;
}
for(int j=2;j<=n;j++)
{
if(a[1][j]==1)
{
bz[1][j][1]=0;
break;
}
else bz[1][j][1]=1;
}
for(int i=2;i<=m;i++)
{
if(a[i][1]==1)
{
bz[i][1][1]=0;
break;
}
else bz[i][1][1]=1;
}
for(int i=2;i<=m;i++)
for(int j=2;j<=n;j++)
{
if(a[i][j]==1)
{
bz[i][j][1]=0;
continue;
}
else add(i,j);
}
for(int i=bz[m][n][0];i>=2;i--)
{
if(flag==false&&bz[m][n][i]==0) continue;
else
{
flag=true;
printf("%d",bz[m][n][i]);
}
}
printf("%d",bz[m][n][1]);
return 0;
}