Advertisement

第十二届蓝桥杯 2021年省赛B组c++部分题解

阅读量:

第一题:空间

解析:1mb=1024kb=1024*1024b,1b(字节)=8bit(位)

复制代码
 #include<bits/stdc++.h>

    
 using namespace std;
    
 int main()
    
 {
    
 	long long a=pow(2,20);
    
 	a=a/4;
    
 	cout<<a*256;
    
 	return 0;	
    
 }

第二题:卡片

复制代码
 #include<bits/stdc++.h>

    
 using namespace std;
    
 typedef long long ll;
    
 ll n=2021041820210418;
    
 ll a[10000];
    
 int main()
    
 {
    
 	int cnt=0;
    
 	for(ll i=1;i*i<=n;i++)
    
 	{
    
 		if(n%i==0)
    
 		{
    
 			a[cnt++]=i;
    
 			if(i!=n/i) a[cnt++]=n/i;
    
 		}
    
 	}	
    
 	int ans=0;
    
 	for(int i=0;i<cnt;i++)
    
 	{
    
 		for(int j=0;j<cnt;j++)
    
 		{
    
 			if(a[i]*a[j]>n) continue;
    
 			for(int k=0;k<cnt;k++)
    
 			{
    
 				if(a[i]*a[j]*a[k]==n) ans++;
    
 			}
    
 		}
    
 	}
    
 	cout<<ans;
    
 	return 0;
    
 }

第三题:直线

复制代码
 #include<bits/stdc++.h>

    
 using namespace std;
    
 struct node{
    
 	double x,y;
    
 };
    
 map<pair<double,double>,int>mp;
    
 node p[500];
    
 int main()
    
 {
    
 	int cnt=0;
    
 	int ans=0;
    
 	for(int i=0;i<20;i++)
    
 	{
    
 		for(int j=0;j<21;j++)
    
 		{
    
 			p[cnt].x=i;
    
 			p[cnt].y=j;
    
 			cnt++;
    
 		}
    
 	}
    
 	for(int i=0;i<cnt;i++)
    
 	{
    
 		for(int j=0;j<cnt;j++)
    
 		{
    
 			if((p[i].x==p[j].x)||(p[i].y==p[j].y)) continue;
    
 			double k=(p[j].y-p[i].y)/(p[j].x-p[i].x);
    
 			double b=(p[j].y*(p[j].x-p[i].x)-p[j].x*(p[j].y-p[i].y))/(p[j].x-p[i].x);
    
 			//double b = p[j].y - k * p[j].x; 不用这种方法,避免k造成精度爆炸
    
 			if(mp[{k,b}]==0)
    
 			{
    
 				mp[{k,b}]=1;
    
 				ans++;
    
 			}
    
 		}
    
 	}
    
 	ans+=20+21;//直线 
    
 	cout<<ans;
    
 	return 0;
    
 }

第四题:货物摆放

复制代码
 #include<bits/stdc++.h>

    
 using namespace std;
    
 typedef long long ll;
    
 ll n=2021041820210418;
    
 ll a[10000];
    
 int main()
    
 {
    
 	int cnt=0;
    
 	for(ll i=1;i*i<=n;i++)
    
 	{
    
 		if(n%i==0)
    
 		{
    
 			a[cnt++]=i;
    
 			if(i!=n/i) a[cnt++]=n/i;
    
 		}
    
 	}	
    
 	int ans=0;
    
 	for(int i=0;i<cnt;i++)
    
 	{
    
 		for(int j=0;j<cnt;j++)
    
 		{
    
 			if(a[i]*a[j]>n) continue;
    
 			for(int k=0;k<cnt;k++)
    
 			{
    
 				if(a[i]*a[j]*a[k]==n) ans++;
    
 			}
    
 		}
    
 	}
    
 	cout<<ans;
    
 	return 0;
    
 }

第五题:路径

解法一:Floyd(运行时间较长)

复制代码
 #include<bits/stdc++.h>

    
 using namespace std;
    
 typedef long long ll;
    
 ll INF=1e9;
    
 ll a[2050][2050];
    
 int gcd(int a,int b)
    
 {
    
 	if(a%b==0) return b;
    
 	return gcd(b,a%b);
    
 }
    
 int main()
    
 {
    
 	for(int i=1;i<=2021;i++)
    
 	{
    
 		for(int j=1;j<=2021;j++)
    
 		{
    
 			if(i==j) a[i][j]=0;
    
 			else if(abs(j-i)>21) a[i][j]=INF;
    
 			else{
    
 				a[i][j]=(i*j)/gcd(j,i);
    
 			}
    
 		}
    
 	}
    
 	for(int k=1;k<=2021;k++)
    
 	{
    
 		for(int i=1;i<=2021;i++)
    
 		{
    
 			for(int j=1;j<=2021;j++)
    
 			{
    
 				a[i][j]=min(a[i][k]+a[k][j],a[i][j]);
    
 			}
    
 		}
    
 	}
    
 	cout<<a[1][2021];
    
 	return 0;
    
 }

解法二:Dijkstra

复制代码
 #include<bits/stdc++.h>

    
 using namespace std;
    
 typedef long long ll;
    
 int INF=1e9;
    
 int a[2050][2050];
    
 int vis[2050];
    
 int d[2050];
    
 int gcd(int a,int b)
    
 {
    
 	if(a%b==0) return b;
    
 	return gcd(b,a%b);
    
 }
    
 void dijk(int s)
    
 {
    
 	fill(d,d+2050,INF);
    
 	d[s]=0;
    
 	for(int i=1;i<=2021;i++)
    
 	{
    
 		int u=-1,mind=INF;
    
 		for(int j=1;j<=2021;j++)
    
 		{
    
 			if(!vis[j]&&d[j]<mind)
    
 			{
    
 				u=j;
    
 				mind=d[j];
    
 			}
    
 		}
    
 		if(u==-1) return;
    
 		vis[u]=1;
    
 		for(int v=1;v<=2021;v++)
    
 		{
    
 			if(!vis[v]&&a[u][v]!=INF&&d[v]>d[u]+a[u][v])
    
 			{
    
 				d[v]=d[u]+a[u][v];
    
 			}
    
 		}
    
 	}
    
 }
    
 int main()
    
 {
    
 	for(int i=1;i<=2021;i++)
    
 	{
    
 		for(int j=1;j<=2021;j++)
    
 		{
    
 			if(i==j) a[i][j]=0;
    
 			else if(abs(j-i)>21) a[i][j]=INF;
    
 			else{
    
 				a[i][j]=(i*j)/gcd(j,i);
    
 			}
    
 		}
    
 	}
    
 	dijk(1);
    
 	cout<<d[2021];
    
 	return 0;
    
 }

第六题:时间显示

复制代码
 #include<bits/stdc++.h>

    
 using namespace std;
    
 typedef long long ll;
    
 int main()
    
 {
    
 	ll n;
    
 	int t;
    
 	scanf("%d",&t);
    
 	while(t--)
    
 	{
    
 		scanf("%lld",&n);
    
 		ll d=24*60*60*1000;
    
 		n=n%d;
    
 		n=n/1000;
    
 		int hh=n/3600;
    
 		int mm=(n/60)%60;
    
 		int ss=n%60;	
    
 		printf("%02d:%02d:%02d\n",hh,mm,ss);
    
 	}
    
 	return 0;
    
 }

第七题:砝码称重

解法一(50%)

复制代码
 #include <bits/stdc++.h>

    
 using namespace std;
    
 typedef long long ll;
    
 const int maxn = 1e6;
    
 int vis[maxn];//记录每种称重是否出现过
    
 int a[maxn];//N个砝码的重量
    
 int N;//砝码的数量
    
 void dfs(int sum, int i)//sum:当前已选用砝码的总重量 i:下一个将要选用砝码的序号
    
 {
    
 	if (i == N)
    
 	{
    
 		if (sum >= 0)
    
 			vis[sum] = 1;
    
 		return;
    
 	}
    
 	dfs(sum + a[i], i + 1);//把a[i]放在右边
    
 	dfs(sum, i + 1);      //不选a[i]
    
 	dfs(sum - a[i], i + 1);//把a[i]放在左边
    
 }
    
 int main()
    
 {
    
 	cin >> N;
    
 	for (int i = 0; i < N; i++) cin >> a[i];
    
 	dfs(0, 0);
    
 	int ans = 0;
    
 	for (int i = 1; i < maxn; i++)
    
 	{
    
 		if (vis[i]) ans++;
    
 	}
    
 	cout << ans << endl;
    
 	return 0;
    
 }

解法二:(100%)

复制代码
 #include <bits/stdc++.h>

    
 using namespace std;
    
 typedef long long ll;
    
 ll dp[100005];//表示重量为j的称重能不能实现,取值为1或0
    
 ll w[105];//N个砝码的重量
    
 int main()
    
 {
    
 	ll N;
    
 	cin >> N;
    
 	for (ll i = 1; i <= N; i++) cin >> w[i];
    
 	dp[0] = 1;
    
 	for (ll i = 1; i <= N; i++) {//考虑每个砝码
    
 		//从大到小考虑每个称重j,j>=w[i]
    
 		//如果从小到大,则意味着w[i]可以加很多次
    
 		for (ll j = 100000; j >= w[i]; j--)//此前没有加w[i],现在考虑加
    
 			//如果此前dp[j - w[i]]为1,则加上w[i]的重量,能达到j,所以dp[j]为1
    
 			dp[j] = max(dp[j], dp[j - w[i]]);
    
 	}
    
 	for (ll i = 1; i <= N; i++) {
    
 		ll siz = 100000 - w[i];
    
 		for (ll j = 1; j <= siz; j++)//此前不放w[i]或放,现在减,相当于放左边和不放
    
 			//如果此前dp[j + w[i]]为1,则减去w[i]的重量,能达到j,所以dp[j]为1
    
 			dp[j] = max(dp[j], dp[j + w[i]]);
    
 	}
    
 	ll ans = 0;
    
 	for (ll i = 1; i <= 100000; i++)
    
 		ans += dp[i];
    
 	cout << ans << endl;
    
 	return 0;
    
 }

第八题:杨辉三角形

复制代码
 #include <bits/stdc++.h>

    
 typedef long long ll;
    
 using namespace std;
    
 ll N;
    
 ll C(int a, int b)
    
 {
    
 	ll res = 1;
    
 	for (ll i = a, j = 1; j <= b; i--, j++)
    
 	{
    
 		res = res * i / j;
    
 		if (res > N)
    
 			return res;
    
 	}
    
 	return res;
    
 }
    
 int main()
    
 {
    
 	cin >> N;
    
 	for (int k = 16; k >= 0; k--)
    
 	{
    
 		ll l = 2 * k, r = max(N, l), mid;
    
 		while (l <= r) {
    
 			mid = l + (r - l) / 2;
    
 			ll CC = C(mid, k);
    
 			if (CC == N)
    
 				break;
    
 			else if (CC > N)
    
 				r = mid - 1;
    
 			else
    
 				l = mid + 1;
    
 		}
    
 		if (C(mid, k) == N)
    
 		{
    
 			cout << (mid + 1) * mid / 2 + k + 1 << endl;
    
 			break;
    
 		}
    
 	}
    
 	return 0;
    
 }

全部评论 (0)

还没有任何评论哟~