C-打牌的贝贝_牛客练习赛105 (nowcoder.com)
题意:
BeiBei和NingNing在玩一个卡牌游戏,共有2n张卡牌,每张牌上都有一个整数,介于1和2n之间,所有牌上的数字都是不同的。发牌阶段二人都拿到了n张牌。每个回合,游戏的过程如下:
1.若此时BeiBei没有牌了,则BeiBei判负。
2.BeiBei打出一张牌。
3.然后NingNing需要打出一张牌,使得其上的数字比BeiBei最新打出的一张牌上的数字大,如果此时NingNing无法打出这样的牌,则NingNing判负。
容易证明,该游戏总有一方会被判负。BeiBei和NingNing都足够聪明。考虑所有可能的分牌情况,使他们每个人正好分到n张牌。当BeiBei和NingNing都足够聪明时,求解出其中BeiBei、NingNing各自获胜的情况数量。
输入描述:
第一行,一个正整数T(1
输出描述:
对于每组数据,输出一行,包含两个整数,分别表示BeiBei、NingNing获胜的情况数量,答案对109+7取模。
题解:
只要后手有n张比先手大的牌即可,类似让一个2*n的字符串有多少正则括号排列方式,
转成括号序列,先手的牌是左括号,后手的牌是右括号,只要是合法的括号序列后手就赢。因此后手的答案就是卡特兰数
这里要引入一个概念卡特兰数

- #include
- using namespace std;
- const int mod = 1e9+7;
- long long fact[2000060],infact[2000060];
- long long qpow(long long a,long long x)
- {
- long long ans = 1;
- while(x)
- {
- if(x&1)
- {
- ans = ans*a%mod;
- }
- x=x/2;
- a=a*a%mod;
- }
- return ans;
- }
- void init()
- {
- fact[0] = infact[0] = 1;
- for(long long i = 1;i <= 2e6;i++)
- {
- fact[i] = fact[i-1]*i%mod;
- infact[i] = infact[i-1]*qpow(i,mod-2)%mod;
- }
- }
- int main()
- {
- init();
- ios::sync_with_stdio(false);
- cin.tie(0);cout.tie(0);
- int t;
- cin >> t;
- while(t--)
- {
- int n;
- cin >> n;
- long long x = fact[2*n]*qpow(infact[n],2)%mod*qpow(n+1,mod-2)%mod;
- cout<
" "<"\n"; - }
- }