尽快收藏蓝桥杯常用算法模板
Posted 合肥编程思维
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尽快收藏蓝桥杯常用算法模板相关的知识,希望对你有一定的参考价值。
又快到了一年一度的蓝桥杯省赛了,涵爸整理了一些蓝桥杯中常考的算法模板分享给大家。
判断闰年
bool isleaf(int x){
return x%400==0||(x%4==0&&x%100!=0);
}
计数月,日或分钟等等
计算日的算法如下,小时分钟和秒就是在此基础上乘以相应的进制即可,月份就是在模板里面month++的时候顺便计数即可。
int syear,smonth,sday; //分别为结束年,月,日
int countday(int year,int month,int day){ //分别为开始的年月日
int ans=0;
int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
while(1){
if(year==syear&&month==smonth&&day==sday){
break;
}
day++;
if(isleaf(year)&&month==2){
if(day>mon[month]+1){
month++;
day=1;
}
}else{
if(day>mon[month]){
month++;
day=1;
}
}
if(month>12){
month=1;
year++;
}
ans++;
}
return ans;
}
筛选素数
筛选素数有许多种方法,首先是最简单的O(n^(3/2))的算法
bool isprime(int n){
if(n==1)return false;
for(int i=2;i*i<n;i++){
if(n%i==0)return false;
}
return true;
}
埃氏筛法O(nloglogn)
埃氏筛法的基本思想:从2开始,将每个质数的倍数都标记成合数,以达到筛选素数的目的
bool visit[MAXN];
void prime(){
memset(visit,false,sizeof(visit); //初始化
visit[0]=visit[1]=true;
for(int i=2;i<=MAXN;i++){
if(!visit[i]){
for(int j=i*i;j<MAXN;j+=i){
visit[j]=true;
}
}
}
}
bool isprime(int n){
return !visit[n];
}
但经过测试埃氏筛在超过100000之后效率不佳,于是就有了欧拉筛
欧拉筛
思想:在埃氏筛的基础之上,让每个合数只被最小质因子筛选一次,以达到不重复。
int prime[MAXN];
int visit[MAXN];
void olprime(){
memset(visit,0,sizeof(visit));
memset(prime,0,sizeof(prime));
for(int i=2;i<=MAXN;i++){
if(!visit[i]){
prime[++prime[0]]=i;
}
for(int j=1;j<=prime[0]&&i*prime[j]<=MAXN;j++){
visit[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
最大公约数gcd
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
最小公倍数lcm
int lcm(int a,int b){
return a*b/gcd(a,b);
}
多个数的gcd和lcm模板
int gcds(int a[],int n){
int g=a[0];
for(int i=1;i<n;i++){
g=gcd(g,a[i]);
}
return g;
}
int lcms(int a[],int n){
int l=a[0];
for(int i=1;i<n;i++){
l=lcm(a[i],l);
}
return l;
}
背包问题
using namespace std;
int main(){
int v[MAXN],w[MAXN],dp[MAXN];
int m,n;//m为总背包大小,n为物品个数
cin>>m>>n;
for(int i=1;i<=n;i++){
cin>>v[i]>>w[i];
}
for(int i=1;i<=n;i++){
for(int j=m;j>=v[i];j--){
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
}
cout<<dp[m];
}
完全背包
using namespace std;
int main(){
int v[MAXN],w[MAXN],dp[MAXN];
int m,n;//m为总背包大小,n为物品个数
cin>>m>>n;
for(int i=1;i<=n;i++){
cin>>v[i]>>w[i];
}
for(int i=1;i<=n;i++){
for(int j=v[i];j<=m;j++){
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
}
cout<<dp[m];
}
两个背包问题的区别就是:01背包每个物品只能选一个,而完全背包问题可以多次选一个物品。
快速幂
ll quickpow(ll a,ll n){
if(n==0||a==1)return 1;
ll ans=1;
while(n!=){
if(n%2==1)ans=a*ans%mod;
a=a*a%mod;
n>>1;
}
return ans;
}
求组合数C(n,m)模板
long long C(int n,int m){
if(m==0)return1;
long long ans=1;
for(int i=n;i>n-m;i--)ans*=i;
for(int i=m;i>1;i--)ans/=i;
return ans;
}
这个算法的缺点在于如果会溢出,long long类型的数字到(83,41)就不能用了,所以我们借助大数
全排列
全排列C++有个叫next_permutation()的函数,这个函数的好处在于能够自动去重全排列,但要注意在操作前一定要将数组或者字符串排序,不然得到的结果不完整。
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> ret;
sort(nums.begin(),nums.end());
do{
ret.emplace_back(nums);
}while(next_permutation(nums.begin(),nums.end()));
return ret;
}
并查集
int n,m,cnt=0;
int f[10005];
int find(int x){
if(f[x]==x)return x;
return f[x]=find(f[x]);
}
void union(int x,int y){
int a=find(x);
int b=find(y);
if(a!=b){
f[a]=b;
cnt++;
}
}
添加涵爸微信,共同交流
~关于涵爸的介绍
标签一:奶爸(这是我最自豪的,没有之一)
8年奶爸生涯刚结束
新一轮奶爸生涯又开始
小二宝悄悄降临
笑声不断,欢乐无穷
标签二:编程高手(这是我给自己封的,有待认可)
才疏学浅,短见薄识
软件开发只有10多年的经验
掌握的C++和Java技能还不够出神入化
前端html、CSS、JS的娴熟度也不足百分
大数据、云计算、人工智能等也只略知一二
虚心万事能成,自满十事九空
涵爸愿虚心学习
不辜负此“高手”二字
标签三:老师(这是自己未来的定位,还需努力)
孩子的教育大于一切
于是我放弃了高薪
编程的普及大势所趋
于是我趟了这趟浑水
能力一般,水平有限
涵爸定当全力以赴
为大家分享最优质的信息
做出最专业的课堂
关注涵爸了解更多少儿编程知识。
以上是关于尽快收藏蓝桥杯常用算法模板的主要内容,如果未能解决你的问题,请参考以下文章
两万字精编~建议抱走蓝桥杯算法竞赛系列第0章——蓝桥必考点及标准模板库STL(下)
[蓝桥杯Python]算法练习算法基础算法训练算法模板(持续更新)