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

来源:互联网 发布:崩坏3矩阵重置 编辑:程序博客网 时间:2024/06/01 10:22

题目:

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
11 1
 

Sample Output
1
思路:当n=m时,结果为1;否则结果为C(max(n,m),min(n,m))。因为要取模以及利用组合的公式,故运用逆元求解,具体看代码~

code:

#include<bits/stdc++.h>using namespace std;#define mod 1000000007int ex_gcd(int a,int b,int &x,int &y){        if(b==0){                x=1;                y=0;                return a;        }        int d=ex_gcd(b,a%b,y,x);        y-=a/b*x;        return d;}int mod_reverse(int a,int n){    int x,y;    int d=ex_gcd(a,n,x,y);    if(d==1) return (x%n+n)%n;    return -1;}int main(){        int t,n,m,i,j,k,num;        scanf("%d",&t);        while(t--){                scanf("%d%d",&n,&m);                if(n==m){                        printf("1\n");                        continue;                }                if(n==1){                        printf("%d\n",m);                        continue;                }                if(1==m){                        printf("%d\n",n);                        continue;                }                if(n<m) swap(n,m);                long long s=1;                for(i=n-m+1;i<=n;i++) s*=i,s%=mod;                for(i=2;i<=m;i++) s=(s*mod_reverse(i,mod))%mod;                printf("%lld\n",s);        }        return 0;}


原创粉丝点击