ZZULI OJ-1894 985的方格难题 【DP or 组合数取余】

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,1)到(n ,n )有多少种走法,每次只能向下或右走,其中有一个格子坏了,不能走;
  2. 思路:两种方法: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),化成阶乘,逆元,快速幂取模;
  3. 失误:unsdiged int 2*1e9,小心超了; c没有long long ; 组合数为什么写不出来呢!
  4. 代码如下:

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值