acwing蓝桥杯刷题

维生素C吃多了会上火-个人CSDN博文目录
2022蓝桥杯

目录

  • 第一讲 递归与递推
    • 1.递归实现指数型枚举
    • 2.递归实现排列型枚举
    • 3.简单斐波那契
    • 4.费解的开关
    • 5.递归实现组合型枚举
    • 6.带分数
    • 7.飞行员兄弟
    • 8.翻硬币
    • 9.总结
  • 第二讲 二分与前缀和
    • 1.数的范围
    • 2.数的三次方根
    • 3.机器人跳跃问题
    • 4.分巧克力
    • 5. 四平方和
    • 6.总结
  • 第三讲 数学与简单DP
    • 1.买不到的数目
    • 2.蚂蚁感冒
    • 3.

第一讲 递归与递推

1.递归实现指数型枚举

#include
using namespace std;
int n;
vector<int> v;
void dfs(int u){//随机多少个
	if(u==n+1){
		for(int i=0;i<v.size();i++) cout<<v[i]<<" ";
		cout<<endl;
		return;
	}
	dfs(u+1);
	
	v.push_back(u);
	dfs(u+1);
	v.pop_back();
}
int main(){
	cin>>n;
	dfs(1);
	return 0;
}

2.递归实现排列型枚举

#include
using namespace std;
int n;

int vis[100];
int a[100];

void dfs(int u){
	if(u==n+1){
		for(int i=1;i<=n;i++) cout<<a[i]<<" ";
		cout<<endl;
		return;
	}

	for(int i=1;i<=n;i++){
		if(vis[i]==1) continue;
		a[u]=i;
		vis[i]=1;
		dfs(u+1);
		vis[i]=0;
	}
}
int main(){
	cin>>n;
	dfs(1);
	return 0;
}

3.简单斐波那契

#include
using namespace std;
int a[100];
int f(int n){
	if(a[n]) return a[n];
	if(n==0) return 0;
    if(n==1||n==2) return 1;
    a[n]=f(n-1)+f(n-2);
	return a[n];
}
int main(){
	int n;
	cin>>n;
	a[0]=0,a[1]=1,a[2]=1;
	f(n-1);
	for(int i=0;i<=n-1;i++){
		cout<<a[i]<<" ";
	}
	return 0;
}

4.费解的开关

#include
using namespace std;
char mp[505][505];
int c[5][2]={{-1,0},{1,0},{0,1},{0,-1},{0,0}};
void turn(int x,int y){
	for(int i=0;i<5;i++){
		int xx = x+c[i][0];
		int yy = y+c[i][1];
		if(xx>=0&&x<5&&yy>=0&&yy<5){
			mp[xx][yy]^=1;
		}
	}
}
int dfs(){
	int minn=30;
	for(int i=0;i<1<<5;i++){ //i=32种按法
		int cnt=0;
		char mem[505][505];
		memcpy(mem,mp,sizeof(mp));
		for(int j=0;j<5;j++){
			if(i>>j&1){ //如果为1表示要按
				turn(0,j);
				cnt++;
			}
		}
		for(int i=1;i<5;i++){
			for(int j=0;j<5;j++){
				if(mp[i-1][j]=='0'){
					turn(i,j);
					cnt++;
				}
			}
		}
		int k;
		for(k=0;k<5;k++){
			if(mp[4][k]=='0'){
				break;
			}
		}
		if(k==5){
			minn = min(cnt,minn);
		}
		memcpy(mp,mem,sizeof(mem));
	}
	return minn>6?-1:minn;
	
}
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		for(int j=0;j<5;j++) cin>>mp[j];
		int status = dfs();
		cout<<status<<endl;
	}
	return 0;
}

5.递归实现组合型枚举

#include
using namespace std;
int n,m;
vector<int> v;
void dfs(int u){
	if(v.size()==m){
		for(int i=0;i<v.size();i++){
			cout<<v[i]<<" ";
		}
		cout<<endl;
		return;
	}
	if(u==n+1){
		return;
	}
	v.push_back(u);
	dfs(u+1);
	v.pop_back();
	
	dfs(u+1);
}
int main(){
	cin>>n>>m;
	dfs(1);
	return 0;
}

6.带分数

#include
using namespace std;
int vis[10];
int a[10];
int cnt=0;
int n;
int num(int x,int y){
	int sum=0;
	for(int i=x;i<=y;i++){
		sum=sum*10+a[i];
	}
	return sum;
}
void judge(){
	for(int i=0;i<9;i++){
		for(int j=i+1;j<9;j++){
			int a=num(0,i);
			int b=num(i+1,j);
			int c=num(j+1,8);
			if(n*c==a*c+b){
				cnt++;
			}
		}
	}
	return;
}
void dfs(int u){
	if(u==9){
		judge();
		return;
	}
	for(int i=1;i<=9;i++){
		if(vis[i]) continue;
		vis[i]=1;
		a[u]=i;
		dfs(u+1);
		vis[i]=0;
	}
}
int main(){
	cin>>n;
	dfs(0);
	cout<<cnt<<endl;
	return 0;
}

7.飞行员兄弟

#include
using namespace std;
char a[5][5];
struct node{
	int x,y;
};
queue<node> que,que2;
void turn(int x,int y){
	if(a[x][y]=='-') a[x][y]='+';
	else a[x][y]='-';
	
	for(int i=0;i<4;i++){
		if(a[i][y]=='-') a[i][y]='+';
		else a[i][y]='-';
		
		if(a[x][i]=='-') a[x][i]='+';
		else a[x][i]='-';
	}
	return;
}
void dfs(){
	int minn=30;
	for(int i=0;i<1<<16;i++){
		int cnt=0;
		char b[5][5];
		memcpy(b,a,sizeof(a));
		for(int c=0;c<4;c++){
			for(int r=0;r<4;r++){
				if(i>>(c*4+r)&1){
					turn(c,r);
					cnt++;
					que.push({c,r});
				}
			}
		}
		bool flag=true;
		for(int c=0;c<4;c++){
			for(int r=0;r<4;r++){
				if(a[c][r]=='+'){
					flag=false;
				}
			}
		}
	    if(flag){
	    	minn = min(minn,cnt);
	    	que2=que;
		} 
		while (!que.empty()) que.pop();
	    memcpy(a,b,sizeof(b));
	}
	cout<<minn<<endl;
	int size = que2.size();
	for(int i=0;i<size;i++){
		cout<<que2.front().x+1<<" ";
		cout<<que2.front().y+1<<endl;
		que2.pop();
	}
}
int main(){
	for(int i=0;i<4;i++) scanf("%s",a[i]);
	dfs();
	return 0;
}

8.翻硬币

#include
using namespace std;
string s,t;
void turn(int x){
	if(s[x]=='*') s[x]='o',s[x-1]='o';
	else s[x]='*',s[x-1]='*';
	return;
}
void dfs(){
	int cnt=0;
	int n=s.length();
	for(int i=1;i<n;i++){
		if(s[i-1]!=t[i-1]){
			turn(i);
			cnt++;
		}
	}
	cout<<cnt<<endl;
	return;
}
int main(){
	cin>>s>>t;
	dfs();
	return 0;
}

9.总结

费解的开关,翻硬币:前面的状态决定了就不会改变,所以由后面的可以改变前面的

飞行员兄弟:前面的状态会受到后面的影响,所以要遍历所有状态

第二讲 二分与前缀和

1.数的范围

#include
using namespace std;
int a[100005];
int main(){
	int n,q;
	cin>>n>>q;
	for(int i=0;i<n;i++) cin>>a[i];
	for(int i=0;i<q;i++){
		int x;
		cin>>x;
		int l=0,r=n-1;
		while(l<r){
			int mid=l+r>>1;
			if(a[mid]>=x) r=mid;
			else l=mid+1;
		}
		if(a[l]!=x) cout<<"-1 -1"<<endl;
		else{
			cout<<l<<" ";
			l=0,r=n-1;
			while(l<r){
				int mid=r+l+1>>1;
				if(a[mid]<=x) l=mid;
				else r=mid-1;
			}
			cout<<l<<endl;
		}
	}
	return 0;
}
#include
using namespace std;
int a[100005];
int main(){
	int n,q;
	cin>>n>>q;
	for(int i=0;i<n;i++) cin>>a[i];
	for(int i=0;i<q;i++){
		int x;
		cin>>x;
		int l = lower_bound(a,a+n,x)-a;
		int r = upper_bound(a,a+n,x)-a;
		if(l>=n||a[l]!=x) cout<<-1<<" "<<-1<<endl;
		else cout<<l<<" "<<r-1<<endl;
	}
	return 0;
}

2.数的三次方根

#include
using namespace std;
int main(){
	double n;
	cin>>n;
	double l=-22,r=22;
	const double eps=1e-8;
	while(r-l>eps){
		double mid=(l+r)/2;
		if(mid*mid*mid>n) r=mid;
		else l=mid;
	}
	printf("%.6lf\n",l);
	return 0;
}

3.机器人跳跃问题

#include
using namespace std;
typedef long long ll;
int a[100005];
int n;
int maxx=0,minn=1e5+1;
bool check(int xx){
	ll x=xx;
	for(int i=0;i<n;i++){
		if(x>a[i]) x=x+(x-a[i]);
		else x=x-(a[i]-x);
		if(x<0) return false;
		if(x>maxx) return true;
	}
	return true;
}
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i];
		maxx=max(maxx,a[i]);
		minn=min(minn,a[i]);
	}
	int l=1,r=maxx;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid)) r=mid;
		else l=mid+1;
	}
	cout<<l<<endl;
	return 0;
}

4.分巧克力

#include
using namespace std;
typedef long long ll;
struct node{
	int x,y;
}a[100005];
int n,k;
bool check(int l){
	int sum=0;
	for(int i=0;i<n;i++){
		sum+=(a[i].x/l)*(a[i].y/l);
	}
	if(sum<k) return false;
	else return true;
}
int main(){
	
	cin>>n>>k;
	int l=1,r=1e5;
	for(int i=0;i<n;i++){
		cin>>a[i].x>>a[i].y;
	}
	while(l<r){
		int mid=l+r+1>>1;
		if(check(mid)) l=mid;
		else r=mid-1;
	}
	cout<<l<<endl;
	return 0;
}

5. 四平方和

在这里插入代码片

6.总结

在确定l , r时候最好就是题目给定的范围

第三讲 数学与简单DP

1.买不到的数目

#include
using namespace std;
int main(){
	int x,y;
	cin>>x>>y;
	int a = (x-1)*(y-1)-1;
	cout<<a<<endl;
	return 0;
}

2.蚂蚁感冒

#include
using namespace std;
typedef long long ll;
int a[60];
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	int x=a[0];
	int num=1;
	bool flag=false;
	int cnt=0;
	if(x<0){
		for(int i=1;i<n;i++){
			if(a[i]>0&&a[i]<abs(x)){
				num++;
				flag=true;
			}
			if(a[i]<0&&abs(a[i])>abs(x)){
				cnt++;
			}
		}
		if(flag) num+=cnt;
	}else{
		for(int i=1;i<n;i++){
			if(a[i]<0&&abs(a[i])>x){
				num++;
				flag=true;
			}
			if(a[i]>0&&a[i]<x){
				cnt++;
			}
		}
		if(flag) num+=cnt;
	}
	cout<<num<<endl;
	return 0;
}

3.

你可能感兴趣的:(蓝桥杯,刷题)