• 石头剪刀布---组合数取模,数论


    https://oj.ismdeep.com/contest/Problem?id=1555&pid=1

    题目描述

    A和B在玩石头剪刀布的游戏(0代表石头,1代表剪刀,2代表布),他们进行了n场游戏,现在A知道B每场的情况,赢一场得一分,输和平不得分,问A最终得分为S的情况有多少种?

    输入

    第一行输入N和S,N表示进行N场游戏,S表示A的得分。(1NS105)

    第二行输入N个数(0,1,2),表示B每场的情况。

    输出

    输出有多少中情况使的A得分为S,数字很大,需要对答案取模109+7

    样例输入

    3 1
    0 1 2

    样例输出

    12

    提示

    费马小定理

    题解:就是求C(n,s)*2n-s,难点在于组合数取模

    #include<iostream>
    #include<math.h>
    #define max 0x3f3f3f3f
    #define ll long long
    #define mod 1000000007
    using namespace std;
    ll pow(ll a, ll b, ll m)
    {
        ll ans = 1;
        a %= m;
        while(b)
        {
            if(b & 1)ans = (ans % m) * (a % m) % m;
            b /= 2;
            a = (a % m) * (a % m) % m;
        }
        ans %= m;
        return ans;
    }
    ll niyuan(ll x, ll p)//x关于p的逆元,p为素数
    {
        return pow(x, p - 2, p);
    }
    ll C(ll n, ll m, ll p)//组合数C(n, m) % p
    {
        if(m > n)
            return 0;
        ll up = 1, down = 1;//分子分母;
        for(int i = n - m + 1; i <= n; i++)
            up = up * i % p;
        for(int i = 1; i <= m; i++)
            down = down * i % p;
        return up * niyuan(down, p) % p;
    }
    ll Lucas(ll n, ll m, ll p)
    {
        if(m == 0)
            return 1;
        return C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
    }
    int main()
    {
        ll n,s,x,temp;
        cin>>n>>s;
        for(ll i=0;i<n;i++)
            cin>>x;
        temp=Lucas(n,s,mod)*pow(2,n-s,mod);
        cout<<temp%mod<<endl;
        return 0;
    }
  • 相关阅读:
    C#类继承情况下构造函数的执行过程
    vs快捷键大全(分类导航)
    vs常用快捷键
    Entity Framework实体无限循环问题
    entity framework实现left join功能
    理解requireJS-实现一个简单的模块加载器
    petshop4.0(王福朋)
    代码覆盖率工具 Istanbul 入门教程
    .net微信开发
    numpy的用法(一)
  • 原文地址:https://www.cnblogs.com/-citywall123/p/10673738.html
Copyright © 2020-2023  润新知