1. 程式人生 > >算法訓練(六)

算法訓練(六)

快速 ace normal amp shee scanf name cas 只有一個

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;
}

算法訓練(六)