Contest - 多校训练(985专场)
Problem C: 985的方格难题
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 329 Solved: 62
SubmitStatusWeb BoardDescription
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
HINT
SubmitStatusWeb BoardAnything about the Problems, Please Contact us
GPL2.0 2003
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=1e2+10,INF=1e9+7;
long long a[MAXN][MAXN];
long long pow(long long n,long long m)
{
if(m==0||n==0) return 0;
long long s=1;long long ss=1,cnt=1;
for(long long i=n;i>=n-m+1;--i)
{
s=s*i/cnt%INF;
++cnt;
// s*=i;
// ss*=cnt++;
}
return s%INF;
}
int main()
{
long long x,y,s,n,m,t,ans,i,j;
memset(a,0,sizeof(a));
for(i=1;i<=64;++i)
{
for(j=1;j<=32;++j)
{
if(i==j)
{
a[i][j]=1;
continue;
}
if(i<j) break;
if(j>i/2)
{
a[i][j]=a[i][i-j];
continue;
}
a[i][j]=pow(i,j);
}
}
scanf("%lld",&t);
while(t--)
{
// scanf("%lld %lld",&n,&m);
// printf("%lld\n",a[n][m]);
scanf("%lld %lld %lld",&n,&x,&y);
if(x==n&&y==n||x==1&&y==1) {
printf("-1\n"); continue;
}
m=x+y-2;
// ans=(pow(2*n-2,n-1)-pow(m,x-1)-pow(m,y-1)-pow(2*n-m-3,n-x))%INF;
ans=(a[2*n-2][n-1]+INF-a[m][x-1]-a[m][y-1]-a[2*n-m-3][n-x])%INF;
// while(ans<0) ans+=INF;
printf("%lld\n",ans);
}
return 0;
}