算法訓練(六)
阿新 • • 發佈:2018-11-24
快速 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> usingnamespace 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; }
算法訓練(六)