蓝桥杯(简单算法模板)

一些进制,日期的计算方法 

  • 电脑带的计算器也是很实用的 

bitset  

  • 求二进制的函数
#include<iostream>
#include<bitset>
using namespace std;
int main(){
	int n,m;
	while(cin>>n>>m){
		bitset<8> t(n);//8:指定几位数 
		bitset<8> tt(m);
		cout<<t<<endl<<tt<<endl;
	} 
	return 0;
}

二维数组前缀和

https://www.acwing.com/problem/content/101/ 

#include<bits/stdc++.h>
#define maxn 5010
using namespace std;

int N,R,ans=1,sum=0;
int a[maxn][maxn];
int main(){
	cin>>N>>R;
	int n=R,m=R;
	for(int i=0,x,y,z;i<N;i++){
		cin>>x>>y>>z;
		x++;y++;n=max(n,x);m=max(m,y);
		a[x][y]+=z;
	} 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1]; 
		}
	}
	int ans=0;
	for(int i=R;i<=n;i++){
		for(int j=R;j<=m;j++){
			ans=max(ans,a[i][j]-a[i][j-R]-a[i-R][j]+a[i-R][j-R]);
		}
	}
	cout<<ans;
	return 0;
}

01背包

for(int i=1;i<=n;i++){
	for(int j=W;j>=w[i];j--){
		dp[j]=max(dp[j],dp[j-w[i]]+v[i]);

 完全背包

	for(int i=1;i<=n;i++)
		for(int j=w[i];j<=V;j++)
				f[j]=max(f[j],f[j-w[i]]+c[i]);

lower_bound(a,a+n,x)-a;

//递增三元组(lower_bound()/upper_bound()函数)
#include<stdio.h>
#include<algorithm>
#define ll long long
const int maxn=100010;
using namespace std;
int a[maxn],b[maxn],c[maxn];
ll sum=0;
int main(){
	int n;scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	for(int i=0;i<n;i++) scanf("%d",&b[i]);
	for(int i=0;i<n;i++) scanf("%d",&c[i]);
	sort(a,a+n);sort(b,b+n);sort(c,c+n);
	for(int i=0;i<n;i++){
		int x=lower_bound(a,a+n,b[i])-a;
		int y=upper_bound(c,c+n,b[i])-c;
		sum+=1ll*x*(n-y);
	}
	printf("%I64d",sum);
} 
//函数lower_bound()在first和last中的前闭后开区间进行二分查找,
//返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置.
//函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val的第一个元素位置

 辗转相除

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll Q(ll n,ll m){
	if(m==0) return n;
	return Q(m,n%m);
}
int main(){
	cout<<Q(15,40)<<endl;
	return 0;
}

欧几里德扩展

https://www.luogu.org/problemnew/show/P1516(同余定理) 

#include<iostream>
#include<cstdio>
#define ll long long 
using namespace std;
ll ans,x1,y1;

ll exgcd(ll a,ll b,ll &x1, ll &y1)
{
    if(!b)
    {
        x1=1;
        y1=0;
        return a;
    }
    ans=exgcd(b,a%b,x1,y1);
    ll t=x1;
    x1=y1;
    y1=t-a/b*y1;
    return ans;
}

int main()
{
    ll n,m,x,y,l;
    cin>>x>>y>>m>>n>>l;
    ll b=n-m,a=x-y;
    if(b<0)
    {
        b=-b;
        a=-a;
    }//处理负数 
    exgcd(b,l,x1,y1);
    if(a%ans!=0)//判断方程有无解。 
        cout<<"Impossible";
    else
        cout<<((x1*(a/ans))%(l/ans)+(l/ans))%(l/ans);//处理负数 
}

加法高精

#include<bits/stdc++.h>
using namespace std;
string a,b;
string gaoji(string a,string b){
	int lena=a.length();
	int lenb=b.length();
	int aa,bb,sum,flag=0;
	while(lena>0){
		aa=a[lena-1]-'0';
		if(lenb>0)
			bb=b[lenb-1]-'0';
		else
			bb=0;
		sum=aa+bb+flag;
		if(sum>=10){
			a[lena-1]='0'+sum%10;
			flag=1;
		} 
		else{
			a[lena-1]='0'+sum;
			flag=0;
		}
		lena--;
		lenb--;
	} 
	if(flag==1)
		a="1"+a;
	return a;
}
int main(){
	cin>>a>>b;
	if(a.size()<b.size())
		swap(a,b);
	cout<<gaoji(a,b)<<endl;
	return 0;
} 

快速幂 

  •  思想:
    • 把10进制看作2进制,用二进制来换算10进制
    • 从最低位找最高位中间的1,来成该位置的幂
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll Q(ll n,ll m){
	ll res=1;
	while(m){
		if(1&m)
			res=res*n;
		n=n*n;
		m>>=1;
	}
	return res;
}
int main(){
	for(int i=1;i<10;i++)
		cout<<Q(2,i)<<endl;
	return 0;
}

归并排序  

//归并排序
#include<bits/stdc++.h>
using namespace std;
int a[100000];
void mergesort(int low,int high){
	if(low>=high) return;
	int mid=(low+high)>>1;
	mergesort(low,mid);
	mergesort(mid+1,high);
	int *b=new int[high-low+1];
	int i=low,j=mid+1,k=0;
	while(i<=mid&&j<=high){
		if(a[i]<a[j])
			b[k++]=a[i++];
		else
			b[k++]=a[j++];
	} 
	while(i<=mid) b[k++]=a[i++];
	while(j<=high) b[k++]=a[j++];
	for(i=low,k=0;i<=high;i++) a[i]=b[k++];
	delete []b;
}
int main(){
	int n;cin>>n;
	for(int i=0;i<n;i++)cin>>a[i];
	mergesort(0,n-1);
	for(int i=0;i<n;i++) cout<<a[i]<<" ";
	return 0;
} 

 插入排序

//定一个flag=0,a[flag]与a[flag+1]比较,满足则交换,
//交换之后,再继续交换排flag之前的数组比较 flag++;
#include<bits/stdc++.h> 
#define ll long long
using namespace std;
int a[40000];
int n,m,x,y,sum=0; 
void cr(int x,int y){
	if(x+1==y) return;
	int flag=x;
	if(a[x]>a[x+1]){
		swap(a[x],a[x+1]);
		for(int i=flag;i>0;i--){
			if(a[i]<a[i-1])swap(a[i],a[i-1]);
		}
	} 
	cr(x+1,y);
}
int main(){
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	cr(0,n);
	for(int i=0;i<n;i++) cout<<a[i]<<" ";
	return 0;
}

选择排序

  • 交换瓶子真题 
//int k=0 在数组小标k到n中找到最小的,与a[k++]交换
#include<bits/stdc++.h> 
#define ll long long
using namespace std;
int a[40000];
int n,m,x,y,sum=0; 
void xz(int a[],int begin,int end){
	if(begin==end) return;
	int main=a[begin],flag=begin;
	for(int i=begin;i<end;i++)
		if(main>a[i]){
			flag=i;
			main=a[i];
		}
	if(a[flag]!=a[begin]){
		swap(a[flag],a[begin]);
		sum++;
	}
	xz(a,begin+1,end);
}
int main(){
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	xz(a,0,n);
	cout<<sum;
	return 0;
}

快速排序

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int a[100];
void Q(int x,int y){
	if(x>y) return;
	int i=x,j=y;
	while(i<j){
		while(a[j]>=a[x]&&i<j)j--;
		while(a[i]<=a[x]&&i<j)i++;
		swap(a[i],a[j]);
	}
	swap(a[x],a[i]);
	Q(x,i-1);
	Q(i+1,y);
}
int main(){
	int n;cin>>n;
	for(int i=0;i<n;i++)cin>>a[i];
	Q(0,n-1);
	for(int i=0;i<n;i++)cout<<a[i]<<" ";
	return 0;
}

优先队列

https://www.luogu.org/problemnew/show/P1090 

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int n,x,ans;
int main(){
   while(scanf("%d",&n)==1){
   		priority_queue<int>q;
   		int sum=0;
   		for(int i=1;i<=n;i++) {
		   cin>>x;	
		   q.push(-x);
   		}
    	for(int i=1;i<n;i++){
    		int w=0;
    		w=q.top();
    		q.pop();
    		w+=q.top();
    		q.pop();
    		q.push(w);
    		sum+=w;
    	}
    	cout<<-1*sum<<endl;
   }
   return 0;
}

简单DFS遍历

   简单dfs历年真题:点击查看 

  • 求起点到终点要走过的的最短步数
  • 障碍物用1表示,无障碍物用0表示
#include<bits/stdc++.h>
using namespace std;
int a[105][105],b[105][105];
int n,m,startx,starty,endx,endy,ans=999999999;
int next[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
void dfs(int x,int y,int step){
	if(x==endx&&y==endy){
		ans=min(ans,step);
		return;
	}
	for(int i=0;i<4;i++){
		int xx=x+next[i][0];
		int yy=y+next[i][1];
		if(xx<1||xx>n||yy<1||yy>m) continue;
		if(a[xx][yy]==0&&b[xx][yy]==0){
			b[xx][yy]=1;
			dfs(xx,yy,step+1);
			b[xx][yy]=0;
		}
	}
	return;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>a[i][j]; 
	cin>>startx>>starty>>endx>>endy;
	dfs(startx,starty,0);
	cout<<ans;
	return 0;
} 

最短路径(暴力)

for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				if(e[i][j]>e[i][k]+e[k][j])
					e[i][j]=e[i][k]+e[k][j];
			}
		}
	} 

欧拉筛

#include<iostream>
#include<string.h>
const int MAX=4e6;
using namespace std;
int prime[MAX],cnt=0;
bool vis[MAX];
void E(int n){
	for(int i=2;i<=n;i++){
		if(!vis[i])
			prime[++cnt]=i;
		for(int j=1;j<=cnt&&prime[j]*i<=n;++j){
			vis[prime[j]*i]=1;
			if(i%prime[j]==0)
				break;
		}
	}
}
int main(){
	int n;cin>>n; 
	memset(vis,0,sizeof(bool)*n);
	E(n);
	for(int i=1;i<=cnt;i++)
		cout<<prime[i]<<endl;
}

读入优化

#include<iostream>
using namespace std;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n;cin>>n;cout<<n;
}
#include<stdio.h> 
#include<iostream>
#include<string.h>
const int MAX=4e6;
using namespace std;
int read(){
	char ch=getchar();
	int x=0,f=1;
	while(ch<'0'||ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}
int main(){
	int x;
	cout<<read();
	return 0;
}

并查集

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int a[10000];
int S(int x){
	if(a[x]==x) return x;
	else{
		a[x]=S(a[x]);
		return a[x];
	}
}
void B(int x,int y){
	int xx=S(x);
	int yy=S(y);
	if(xx!=yy)
		a[yy]=xx;
}
int main(){
	int n,sum=0;cin>>n;
	for(int i=1;i<=n;i++)a[i]=i;
	for(int i=1;i<=n;i++){
		int x,y;cin>>x>>y;
		B(x,y);
	}
	for(int i=1;i<=n;i++)
		if(a[i]==i)
			sum++;
	cout<<sum;
	return 0;
}

阶乘高精

#include<bits/stdc++.h>
using namespace std;
int num[5000];
int gaojing(int num[],int n){
	int len=1;
	num[0]=1;
	for(int i=1;i<=n;i++){
		len=0;
		int p=0;
		int jw=0;
		while(num[p]!=-1){
			num[p]*=i;
			num[p]+=jw;
			jw=0;
			if(num[p]>=10){
				jw=num[p]/10;
				num[p]%=10;
			}
			p++;
			len++;
		}
		if(jw!=0){
			while(jw){
				num[p++]=jw%10;
				jw/=10;
				len++;
			}
		}
	} 
	return len-1;
}

int main(){
	int n;
	while(cin>>n){
		memset(num,-1,sizeof(num));
		int len=gaojing(num,n);
		for(len;len>=0;len--){
			cout<<num[len];
		}
		cout<<endl;
	}
	return 0;
}

vector

#include<bits/stdc++.h>
using namespace std;
vector<int> a[100];
int main(){
	//输入 
	a[10].push_back(50);
	a[10].push_back(10);
	a[10].push_back(100);
	//排序 
	sort(a[10].begin(),a[10].begin()+3);
	//大小 
	cout<<a[10].size()<<endl;
	//输出 
	for(vector<int>::iterator it=a[10].begin();it!=a[10].end();it++){
		cout<<*it<<" ";
	}
	cout<<endl;
	//删除最后一个元素; 
	a[10].pop_back();
	//输出元素 
	for(int i=0;i<a[10].size();i++)
		cout<<a[10][i]<<" "; 
	return 0;
} 

set 

#include<iostream>
#include<set>
using namespace std;
int main(){
	set<int> s;
	s.insert(1);
	s.insert(5);
	s.insert(7);
	s.erase(1);//删除元素 
	for(set<int>::iterator it=s.begin();it!=s.end();it++){
		cout<<*it<<endl;
	} 
	return 0;
}

map

#include<iostream>
#include<map>
using namespace std;
int main(){
	map<string,int>mmp;
	int n;cin>>n;
	for(int i=1;i<=n;i++){
		string  s;
		cin>>s;
		mmp[s]++;
	}
	for(map<string,int>::iterator it=mmp.begin();it!=mmp.end();it++){
		cout<<it->first<<" "<<it->second<<endl;
	}
	return 0;
}

数组长度 

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
char a[1000];
int b[]={1,2,3,4,5,6,7,8,9};
int n;
int main(){
	gets(a);
	puts(a);
	
	cout<<sizeof(a)/sizeof(a[0])<<endl;
	cout<<strlen(a)<<endl;
	cout<<sizeof(b)/sizeof(int);
	return 0;
}

 运算

 

  • &:两个都为1才为1; 
  • | :一个为1都为1;
  • ^:相反为1,其余为0;

sort:字符数字串字典序 

#include<bits/stdc++.h>
using namespace std;
//algorithm
string a[21];
bool cmp(string a,string b){
	return a+b > b+a;//a+b就是字符串的连接,******数字字符串是可以直接比较大小的 
}
int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++)cout<<a[i]<<" ";
	return 0;
} 

substr(string) 

#include<iostream>
using namespace std; 
int main(){
	string s;cin>>s;
	cout<<s.substr(0)<<endl<<s.substr(1)<<endl<<s.substr(0,5)<<endl;
	return 0;
}

sstream 和 atoi

  • 将字符串类型中的最前面数字转换为整数类型
#include<iostream>
#include<sstream>
using namespace std;
int main(){
	int x;string s;
	cin>>s;
	stringstream ss(s);
	ss>>x;
	cout<<x;
	return 0;
}
#include<iostream>
#include<sstream>
#include<cstdlib>
using namespace std;
int main(){
	int x;string s;
	cin>>s;
	x=atoi(s.c_str());
	cout<<x;
	return 0;
}

next_permutation()全排列函数

  • 蓝桥杯好多题都用到了全排列 
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main(){
	string s="1234567";int sum=0;
	do{
		cout<<s<<'\n';
		sum++;
	}while(next_permutation(s.begin(),s.end()));
	cout<<sum<<'\n';
 	return 0;
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值