您的位置:首页 > 其它

2017百度之星初赛:B-1001. Chess

2017-08-13 21:41 155 查看


Chess

 
 Accepts: 1805
 
 Submissions: 5738

 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 32768/32768 K (Java/Others)

Problem Description

車是中国象棋中的一种棋子,它能攻击同一行或同一列中没有其他棋子阻隔的棋子。一天,小度在棋盘上摆起了许多車……他想知道,在一共N×M个点的矩形棋盘中摆最多个数的車使其互不攻击的方案数。他经过思考,得出了答案。但他仍不满足,想增加一个条件:对于任何一个車A,如果有其他一个車B在它的上方(車B行号小于車A),那么車A必须在車B的右边(車A列号大于車B)。
现在要问问你,满足要求的方案数是多少。

Input

第一行一个正整数T,表示数据组数。
对于每组数据:一行,两个正整数N和M(N<=1000,M<=1000)。

Output

对于每组数据输出一行,代表方案数模1000000007(1e9+7)。

Sample Input

1
1 1


Sample Output

1


答案就是C(max(n, m), min(n, m))

不用Lucas也行

#include<stdio.h>
#include<algorithm>
using namespace std;
#define LL long long
LL Pow(LL a, LL b, LL mod);
LL C(LL m, LL n, LL p);
LL Pow(LL a, LL b, LL mod)
{
LL sum;
sum = 1;
while(b)
{
if(b%2==1)
sum = (sum*a)%mod;
a = (a*a)%mod;
b /= 2;
}
return sum;
}
LL C(LL m, LL n, LL p)
{
LL i, ans;
ans = 1;
if(m<n)
return 0;
for(i=1;i<=n;i++)
ans = ans*(((m-n+i)%p)*Pow(i, p-2, p)%p)%p;
return ans;
}
int main(void)
{
LL T, n, m;
scanf("%I64d", &T);
while(T--)
{
scanf("%I64d%I64d", &n, &m);
if(n>m)
swap(n, m);
printf("%I64d\n", C(m, n, 1000000007));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: