2017百度之星初赛(B) 1001 Chess(思维+Lucas)

题目大意:

给你一个 m*n (0< m <1000,0< n <1000)的棋盘,问你在上面放最多的棋子的摆放方法的种数。要求:对于每一个棋子,它的上面每一行的棋子都必须在它的左边。且每一行只能有一个棋子。

分析:

其实仔细考虑,这个问题对棋盘来说是对角线对称的,所以 m n 的顺序对这道题的结果无关。所以现在我们不妨假设: m>n 。首先最多能放的棋子个数肯定是:min(n,m)。然后我们考虑这样一个问题:对于一个m*1的表格,我从中选出 n 个格子放棋子,对于每一种放这 n 个棋子的方式,我将这n个棋子上移至符合要求,都有且只有一种在 n*m 的格子中放这 n 个棋子的方式与其对应。那么,显然总共的摆放方式就是: Cnm

代码:

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int mod=1000000007;
int t,m,n;


LL qmod(LL x,int n)//快速幂取模
{
      LL ans=1;
      for(;n;n>>=1)
      {
            if(n&1)ans=(ans*x)%mod;
            x=x*x%mod;
      }
      return ans;
}
LL C(int n,int m)//组合数取模
{
      if(m>n)return 0;
      LL ans=1;
      for(int i=1;i<=m;i++)
      {
            ans=ans*((n-m+i)*qmod(i,mod-2)%mod)%mod;
      }
      return ans;
}


int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);//n<m
        int temp=0;
        if(n>m)
        {
            temp=n;
            n=m;
            m=temp;
        }
        printf("%d\n",C(m,n)%mod);
    }

}
全部评论

相关推荐

回家当保安:加油, 我当时也想拒字节面试,是被HR鼓励着我面试。然后走了2周流程 ,一共3+1 面,最后惊喜的发了offer。佬可以试试
点赞 评论 收藏
分享
专业嗎喽:个人信息名字太大,合到电话邮箱那一栏就行,有党员写过党,剩下其他全删,站空太大了 把实习经历丰富,放最前面,然后是个人评价,技能之类的,然后是学校信息。项目经历最后面,可以就选一个自己擅长的。 现在是学校不是92就扣分的,没必要放前面。 然后现在看重实习经历>竞赛经历(校园经历)>课程项目经历
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务