算法训练(六)

1.gym 101775A

本题是一个 C(n,k)+C(n,k+1)+...+C(n,n) 的过程,暴力会超时,转化为 2^n - C(n,0)+C(n,1)+...+C(n,k-1);

利用费马小定理(假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p),即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。)

得到推论  a*a(p-2)≡1(mod p)对于整数a,p,a关于p的逆元就是a^(p-2);

#include <iostream>
#include <stdio.h>

using namespace std;
typedef long long ll;
const int N=1e5+7;
const ll mod=1e9+7;

ll quick(ll a,ll b)            //快速幂
{
    ll ans=1;
    a%=mod;
    while(b){
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}

int main()
{
    ll n,k,i;
    int l=1,t;
    scanf("%d",&t);
    while(t--){
        scanf("%I64d%I64d",&n,&k);
        ll ans=quick(2,n)-1;      //2^n-C(n,0)
        ll cur=n;
        for(i=1;i<k;i++){
            ans=(ans+mod-cur)%mod;       //计算过程中一直模mod 所以可能会出现ans<cur的情况 为防止出现ans-cur为负数 所以要+mod
            cur=cur*(n-i)%mod;
            cur=cur*quick(i+1,mod-2)%mod;        //乘以逆元
        }
        printf("Case #%d: %I64d\n",l++,ans);
    }
    return 0;
}

 2.gym 101775L

首先s_ _s是个必胜态,这是题目的突破口,通过模拟可以发现当格数小于等于7的时候最优解是平局,以此类推大于等于7的奇数先手的panda必胜;大于等于16的偶数先手panda(必下o)留给后手sheep存在连续空格大于等于7的一共奇数个格子,sheep必胜;

这种题目就是靠模拟得结论,也没什么好办法

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,t,cas=0;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        if(n>=16&&n%2==0) printf("Case #%d: Sheep\n",++cas);
        else if(n>=7&&(n&1))printf("Case #%d: Panda\n",++cas);
        else printf("Case #%d: Draw\n",++cas);
    }
    return 0;
}

 3.gym 101775m

这道题只要能看懂而且对世界杯规则有所了解毫无难度。。。

#include <bits/stdc++.h>
using namespace std;
int num[70];
int main()
{
    int T;
    int a;
    int N;
    long long coun=0;
    scanf("%d",&T);
for(int k=1;k<=T;k++)
{
    coun=0;
   for(int i=1;i<=5;i++)
   {
       scanf("%d",&a);
       if(i==1)
        for(int j=1;j<=48;j++)
        num[j]=a;
       if(i==2)
        for(int j=49;j<=56;j++)
        num[j]=a;
        if(i==3)
        for(int j=57;j<=60;j++)
        num[j]=a;
         if(i==4)
        for(int j=61;j<=62;j++)
        num[j]=a;
         if(i==5)
        num[63]=a;
   }
   scanf("%d",&N);
   while(N--)
   {
       scanf("%d",&a);
       coun+=num[a];
   }
   printf("Case #%d: %lld\n",k,coun*10000);
}
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/KasenBob/p/10011414.html