985的方格难题
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 395 Solved: 87
SubmitStatusWeb Board
Description
985走入了一个n * n的方格地图,他已经知道其中有一个格子是坏的。现在他要从(1, 1)走到(n, n),每次只可以向下或者向右走一步,问他能否到达(n,n)。若不能到达输出-1,反之输出到达(n,n)的方案数。
Input
第一行输入一个整数t,代表有t组测试数据。
每组数据第一行输入三个整数n,x,y,分别代表方格地图的大小以及坏掉格子的位置。
注:1 <= t <= 20,1 <= n <= 30,1 <= x,y <= n。
Output
若可以到达(n,n)则输出方案数对1e9 + 7取余的结果,反之输出-1。
Sample Input
2
2 1 2
2 2 2
Sample Output
1
-1
- 题意:求从(1,1)到(n ,n )有多少种走法,每次只能向下或右走,其中有一个格子坏了,不能走;
- 思路:两种方法:dp:可以递推出到当前方案数dp[i][j]=dp[i][j-1]+dp[i-1][j] ; 组合数:先求出不含坏格子的方案数C(2*n-2,n-1),通过坏格子的方案数为C(x+y-2,x-1) *C(2×n-x-y,n-x),化成阶乘,逆元,快速幂取模;
- 失误:unsdiged int 2*1e9,小心超了; c没有long long ; 组合数为什么写不出来呢!
- 代码如下:
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=1e2+10,INF=1e9+7;//习惯就是容易被忽略 都两次写成+10了 以后得变一变
int map[MAXN][MAXN];
int main()
{
int t,n,i,j,x,y;
scanf("%d",&t);
while(t--)
{
scanf("%d %d %d",&n,&x,&y);
memset(map,0,sizeof(map));
if(x==n&&y==n||x==1&&y==1)//特殊的分开最好考虑
{
printf("-1\n"); continue;
}
map[1][1]=1;//初始化一种方案
for(i=1;i<=n;++i)
{
for(j=1;j<=n;++j)
{
if(i==1&&j==1) continue;//坏得格子0种
if(!(i==x&&j==y))
map[i][j]=(map[i-1][j]%INF+map[i][j-1]%INF)%INF;
}
}
printf("%d\n",map[n][n]);
}
return 0;
}