算法训练
Posted kasenbob
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法训练相关的知识,希望对你有一定的参考价值。
本题是一个 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 ",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 ",++cas); else if(n>=7&&(n&1))printf("Case #%d: Panda ",++cas); else printf("Case #%d: Draw ",++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 ",k,coun*10000); } return 0; }
以上是关于算法训练的主要内容,如果未能解决你的问题,请参考以下文章
有人可以解释啥是 SVN 平分算法吗?理论上和通过代码片段[重复]
片段(Java) | 机试题+算法思路+考点+代码解析 2023