题目描述
A和B在玩石头剪刀布的游戏(0代表石头,1代表剪刀,2代表布),他们进行了n场游戏,现在A知道B每场的情况,赢一场得一分,输和平不得分,问A最终得分为S的情况有多少种?
输入
第一行输入N和S,N表示进行N场游戏,S表示A的得分。(1≤N,S≤105)
第二行输入N个数(0,1,2),表示B每场的情况。
输出
输出有多少中情况使的A得分为S,数字很大,需要对答案取模109+7
。
样例输入
3 1
0 1 2
样例输出
12
题目链接https://oj.ismdeep.com/contest/problem?id=1555&pid=1
思路:由题目可以的出解为Cn,s 2^n-s%mod
但是由于无法做到整除所以必须把A/B变为AC形式
根据费马小定理得:当A与mod互质时,B^mod-2次方就是B的逆元,即C;
所以有以下代码:
#include "bits/stdc++.h"
#define ll long long
int mod=1000000007;
using namespace std;
ll f(ll a,ll b)
{
ll sum=1;
while(b>0)
{
if(b&1)
{
sum=(sum*a)%mod;
}
a=a*a%mod;
b>>=1;
}
return sum;
}
ll f1(int n,int s)
{
ll sum=1;
for(int i=1,j=n;i<=s;i++,j--)
{
sum=((sum*j)%mod*f(i,mod-2)%mod)%mod;//f(i,mod-2)就是j/i%mod=1时i的逆元
}
return sum;
}
int main(int argc, char const *argv[]) {
int n,s;
cin>>n>>s;
int a;
for(int i=0;i<n;i++)
{
cin>>a;
}
cout<<f(2,n-s)*f1(n,s)%mod<<endl;
return 0;
}
**1.void exgcd(int a,int b,int &x,int &y)//求ax+by=gcd(a,b)得解x,y。
{
if(b==0)
{
x=1,y=0;return ;}
exgcd(b,a%b,x,y)
int tmp=x;
x=y;
y=tmp-(a/b)*y;
}
1.如果a,b互质即方程为ax+by=1; 当b==0则 ax=1;得出得x即为a得逆元;y为b的逆元
注:x,y是任意的