第十二届蓝桥杯题解

第十二届蓝桥杯题解

A:卡片

暴力枚举即可

#include<bits/stdc++.h>
using namespace std;
int a[10];
int flag=0;
int main(){
	for(int i=1;i<=10000;i++){
		if(flag==1) break;
		int j=i;
		while(j){
			int len=j%10;
			a[len]++;
			if(a[len]>2021){
				flag=1;
				if(j==0)
				cout<<i<<endl;
				else cout<<i-1<<endl;
				break;
			}
			j/=10;
		}
	}
}

B直线

暴力枚举即可

#include<bits/stdc++.h>
using namespace std;
struct node{
	double k;
	double b;
};
bool cmp(node a,node b){
	if(a.k!=b.k) return a.k<b.k;
	else return a.b<b.b;
}
int n=0;
node l[2000000];
int main(){
	for(int x1=0;x1<20;x1++)
	for(int y1=0;y1<21;y1++)
	for(int x2=0;x2<20;x2++)
	for(int y2=0;y2<21;y2++)
	if(x1!=x2){
		double k=(double)(y2-y1)/(x2-x1);
		double b=y1-k*x1;
		l[n].k=k;
		l[n].b=b;
		n++;
	}
	sort(l,l+n,cmp);
	int sum=1;
	for(int i=1;i<n;i++){
		if(fabs(l[i].k-l[i-1].k)>1e-3||fabs(l[i].b-l[i-1].b)>1e-8){
			sum++;
		}
	}
	cout<<sum+20<<endl;
}

C:货物摆放

暴力枚举即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<ll>v;
int main(){
	ll n=2021041820210418;
	for(ll i=1;i*i<=n;i++){
		if(n%i==0){
			v.push_back(i);
			if(n/i!=i){
				v.push_back(n/i);
			}
		}
	}
	ll sum=0;
	for(vector<ll>::iterator a=v.begin();a!=v.end();a++)
	for(vector<ll>::iterator b=v.begin();b!=v.end();b++)
	for(vector<ll>::iterator c=v.begin();c!=v.end();c++)
	if(*a*(*b)*(*c)==n) sum++;
	cout<<sum<<endl;
}

D:路径

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int edge[2030][2030];
int visit[2030];
int path[2030];
int gcd(int x,int y){
	if(y==0) return x;
	return gcd(y,x%y);
}
int lcm(int x,int y){
	return x/gcd(x,y)*y;
}
int main(){
	memset(edge,INF,sizeof(edge));
	for(int i=1;i<=2021;i++){
		for(int j=i+1;j<=2021;j++){
			if(j-i>21) continue;
			int cost=lcm(i,j);
			edge[i][j]=cost;
			edge[j][i]=cost;
		}
	}
	memset(visit,0,sizeof(visit));
	memset(path,INF,sizeof(path));
	path[1]=0;
	for(int i=1;i<=2021;i++){
		int start;
		int minn=INF;
		for(int j=1;j<=2021;j++){
			if(!visit[j]&&path[j]<=minn){
				minn=path[j];
				start=j;
			}
		}
		visit[start]=1;
		for(int j=1;j<=2021;j++){
			path[j]=min(path[j],path[start]+edge[start][j]);
		}
	}
	cout<<path[2021];
}

E:回路计数

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=(1<<21);
int gcd(int x,int y){
	if(y==0) return x;
	return gcd(y,x%y);
}
bool judge(int x,int y){
	if(gcd(x,y)==1) return true;
	return false;
}
int maps[30][30];
ll dp[maxn][30];
int main(){
	for(int i=1;i<=21;i++){
		for(int j=1;j<=21;j++){
			if(judge(i,j)){
				maps[i][j]=1;
			}
		}
	}
	ll num=(1<<21)-1;//最多是所有点都走过的情况 
	dp[1][1]=1;//经过1到达1的方案数为1 
	for(int i=1;i<=num;i++){//i的二进制表示有没有到达过某个点二进制位为1表示到达过,为0表示没到达过 
		for(int j=1;j<=21;j++){
			if((i>>(j-1)&1)){//j位到达过,即能到达j位 
				int q=i-(1<<(j-1)); //把到j位的情况删去求到达j的方法有多少种 
				for(int k=1;k<=21;k++){
					if(maps[k][j]==1&&((q>>(k-1))&1)==1){//K到j有路可走并且到达过k 
						dp[i][j]+=dp[q][k];
					}
				}
			} 
		}
	}
	ll ans=0;
	for(int i=1;i<=21;i++){
		ans+=dp[(1<<21)-1][i];//求所有的都到过的情况有多少种 
	}
	cout<<ans<<endl; 
}

E:砝码称重

#include<bits/stdc++.h>
using namespace std;
int a[110];
int dp[105][200005];
int main(){
	int n;
	cin>>n;
	long long sum=0;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum+=a[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=sum;j++){
			dp[i][j]=dp[i-1][j];
			if(!dp[i][j]){
				if(j==a[i]) dp[i][j]=1;
				if(dp[i-1][j+a[i]]) dp[i][j]=1;
				if(dp[i-1][abs(j-a[i])]) dp[i][j]=1;
			}
		}
	}
	long long ans=0;
	for(int j=1;j<=sum;j++){
		if(dp[n][j]) ans++;
	}
	cout<<ans<<endl;
}

F:异或数列

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll num[23];
ll a;
void pre(ll a){
	ll cnt=1;
	while(a){
		if(a&1) num[cnt]++;
		cnt++;
		a/=2;
	}
}
int main(){
	int t;
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>t;
	while(t--){
		memset(num,0,sizeof(num));
		int n,sum=0;
		cin>>n;
		for(int i=0;i<n;i++){
			cin>>a;
			pre(a);
			sum^=a;
		}
		if(!sum)cout<<0<<endl;
		else{
			for(int i=20;i>0;i--){
				if(num[i]==1){
					cout<<1<<endl;
					break;
				}
				else if(num[i]%2==1){
					if(n%2==1){
						cout<<1<<endl;
						break;
					}
					else {
						cout<<-1<<endl;
						break;
					}
				}
				}
			}
		}
	} 

G:左孩子右兄弟

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
vector<int>g[maxn];
int dfs(int u){
	int len=g[u].size();
	int res=len;
	int maxn=0;
	for(int i=0;i<len;i++){
		maxn=max(maxn,dfs(g[u][i]));
	}
	res+=maxn;
	return res;
}
int main(){
	int n;
	cin>>n;
	for(int i=2;i<=n;i++){
		int a;
		cin>>a;
		g[a].push_back(i);
	}
	int ans=dfs(1);
	cout<<ans<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值