2017"百度之星"程序设计大赛

来源:互联网 发布:windows samba 编辑:程序博客网 时间:2024/06/05 06:20

【中文题意】
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
Copy
1
1 1
Sample Output
1
【思路分析】
结果就是C(min(n,m),max(n,m))。这个可以稍微推一下便可以得到结果。
【AC代码】

#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<map>#include<stack>#include<queue>#include<set>using namespace std;#define LL long long#define maxn 100005const LL mod = 1e9+7;LL pow_mod(LL a, LL b, LL p){    LL res = 1;    while(b != 0)    {        if(b&1) res = (res * a) % p;        a = (a*a) % p;        b >>= 1;    }    return res;}LL Comb(LL a, LL b, LL p){    if(a < b)   return 0;    if(a == b)  return 1;    if(b > a - b)   b = a - b;    LL ans = 1, ca = 1, cb = 1;    for(LL i = 0; i < b; ++i)    {        ca = (ca * (a - i))%p;        cb = (cb * (b - i))%p;    }    ans = (ca*pow_mod(cb, p - 2, p)) % p;    return ans;}LL Lucas(int n, int m, int p){    LL ans = 1;    while(n&&m&&ans)    {        ans = (ans*Comb(n%p, m%p, p)) % p;        n /= p;        m /= p;    }    return ans;}int main(){    int t;    LL m,n;    scanf("%d",&t);    while(t--)    {        LL n1,m1;        scanf("%lld%lld",&m,&n);        if(m==n)        {            printf("1\n");            continue;        }        if(m>n)        {            n1=m;            m1=n;        }        else        {            n1=n;            m1=m;        }        printf("%lld\n", Lucas(n1, m1, mod));    }    return 0;}
原创粉丝点击