2023第十四届蓝桥杯国赛 C/C++ 大学 B 组

 省赛还水了个省一,国赛原型毕露了

参考文献:(13条消息) 2023第十四届蓝桥杯国赛 C/C++ 大学 B 组_旧林墨烟的博客-CSDN博客

(13条消息) 2023第十四届蓝桥杯国赛 C/C++ 大学 B 组 (赛后记录)_.Zero的博客-CSDN博客

A:子2023 

【问题描述】
小蓝在黑板上连续写下从 1 到 2023 之间所有的整数,得到了一个数字序列:
S = 12345678910111213 . . . 20222023。
小蓝想知道 S 中有多少种子序列恰好等于 2023?
提示,以下是 3 种满足条件的子序列(用中括号标识出的数字是子序列包含的数字):
1[2]34567891[0]111[2]1[3]14151617181920212223…
1[2]34567891[0]111[2]131415161718192021222[3]…
1[2]34567891[0]111213141516171819[2]021222[3]…
注意以下是不满足条件的子序列,虽然包含了 2、0、2、3 四个数字,但是顺序不对:
1[2]345678910111[2]131415161718192[0]21222[3]…

暴力枚举 +剪枝  (考试的时候怎么就没敢做哪?)

答案:5484660609

#include<bits/stdc++.h>
using namespace std;
const int MAX=2e5+10;
typedef long long ll;
#define x first 
#define y second 
typedef pair<int,int>PII;
ll sum,cnt,target;
ll dp[2500][20]; 
int main()
{
	string s;
	for(int i=1;i<=2023;i++)
	{
		int x=i;
		string t=to_string(i);
		for(int j=0;j<t.size();j++)
		{//光把数字中的2/3/0加进来,剪枝 
			if(t[j]=='2'||t[j]=='3'||t[j]=='0')s+=t[j];
		}
	}
	ll cnt=0;
	int n=s.size();
	cout<<s<<endl;
	for(int i=0;i<n;i++)
	{
		if(s[i]=='2')
		{
			for(int j=i+1;j<n;j++)
			{
				if(s[j]=='0')
				{
					for(int k=j+1;k<n;k++)
					{
						if(s[k]=='2')
						{
							for(int p=k+1;p<n;p++)
							{
								if(s[p]=='3')cnt++;
							}
						}
					}
				}
			}
		}
	}
	cout<<cnt;
	return 0;
}

 dp 上面链接大佬的思路,太牛了

当遇到字符 ‘2’ 的时候字符串 “2” 的数量+1,字符串 “202” 的数量加上字符串 “20” 的数量
当遇到字符 ‘0’ 的时候字符串 “20” 的数量加上字符串 “2” 的数量
当遇到字符 ‘3’ 的时候字符串 “2023” 的数量加上字符串 “202” 的数量
最后 “2023” 的数量就是答案

#include<bits/stdc++.h>
using namespace std;
const int MAX=2e5+10;
typedef long long ll;
#define x first 
#define y second 
typedef pair<int,int>PII;
ll sum,cnt,target;
ll dp[4]; //dp四个分别代表 '2' ,'20' ,'202' ,'2023'的数量 
int main()
{
	string s;
	for(int i=1;i<=2023;i++)
	{
		int x=i;
		string t=to_string(i);
		for(int j=0;j<t.size();j++)
		{//光把数字中的2/3/0加进来,剪枝 
			if(t[j]=='2'||t[j]=='3'||t[j]=='0')s+=t[j];
		}
	}
	int n=s.size();
	for(int i=0;i<n;i++)
	{
		if(s[i]=='2')
		{
			dp[0]++;//'2'数量++ 
			dp[2]+=dp[1]; //进来一个2,'202'数量加上'20'的数量	
		}	
		else if(s[i]=='0')
		{
			dp[1]+=dp[0];//进来一个0,'20'数量加上‘2’的数量 
		}
		else if(s[i]=='3')
		{
			dp[3]+=dp[2]; //进来一个3,'2023'数量加上'202'数量 
		}
	}
	cout<<dp[3]; 
	return 0;
}

B: 双子数

【问题描述】
  若一个正整数 x 可以被表示为 p2 × q2,其中 p、q 为质数且 p , q,则 x 是一个 “双子数”。请计算区间 [2333, 23333333333333] 内有多少个 “双子数”?

考试的时候暴力没搜出来--  以后要习惯暴力找剪枝

long long 开不下prime[i]*prime[i]*prime[j]*prime[j]   错误结果是 947303

要用__int128   

答案  947293

#include<bits/stdc++.h>
using namespace std;
const int MAX=2e5+10;
typedef long long ll;
#define x first 
#define y second 
#define int __int128
typedef pair<int,int>PII;
ll sum,cnt,target;
bool isPrime(ll x)
{
	if(x==2||x==3||x==5)return true;
	for(ll i=2;i<=sqrt(x);i++)
	{
		if(x%i==0)return false;
	} 
	return true;
}
signed main()
{
	vector<int>prime;
	ll left=2333,right=23333333333333;
	for(int i=2;i<=sqrt(right);i++)
	{//不会用筛 就暴力了 
		if(isPrime(i))
		prime.push_back(i);
	}
	cout<<"hehe\n";
	for(int i=0;i<prime.size();i++)
	{
		for(int j=i+1;j<prime.size();j++)
		{
			int res=prime[i]*prime[j];
			if(res>=sqrt(left)&&res<=sqrt(right))cnt++;
			if(res>sqrt(right))break;//大于直接退出 ,后面的更大,所以后面没答案 ——剪枝 
		}
	}
	cout<<cnt;
	return 0;
}

C题 班级活动

找规律     

sum1存人数多于两个的人数去掉匹配的 2 位剩下的总人数 下面记作集合S 
    sum2存储出现一次的, 这是单个的需要处理的    下面记作集合V
    如果sum1>=sum2  res=sum1 把集合S中的和V中的匹配sum1-sum2个,剩下S的sum2个两两匹配成其他未出现的数
    例子 1 1 1 1  1 2 2 2 3 4  
    需处理的是 1 1  1 2, 3 4  把左边任意两个和右边两个匹配(1 1 便 3 4),左边剩下两个随便换一个(1 2 换 6 6(没出现的都行)) 
    如果sum1<sum2  S和V所有匹配,V剩下的两两匹配 
    1 1 1 2 2 2 2 3 4 5 6  7
    需要处理 1  2 2 ,3 4 5 6 7 
    把左边三个和右面三个匹配(1 2 2 变为 3 4 5),右面剩下两个自己匹配 (6 7 变 6 6)

#include<bits/stdc++.h>
using namespace std;
const int MAX=2e5+10;
#define x first 
#define y second 
#define int long long
typedef pair<int,int>PII;
signed main()
{
	int n;
	cin>>n;
	map<int,int>mymap;
	for(int i=0;i<n;i++)
	{
		int x;
		cin>>x;
		mymap[x]++;
	}
	int sum1=0,sum2=0;
	/*sum1存人数多于两个的人数去掉匹配的 2 位剩下的总人数 下面记作集合S 
	sum2存储出现一次的, 这是单个的需要处理的    下面记作集合V
	如果sum1>=sum2  res=sum1 把集合S中的和V中的匹配sum1-sum2个,剩下S的sum2个两两匹配成其他未出现的数
	例子 1 1 1 1  1 2 2 2 3 4  
	需处理的是 1 1  1 2, 3 4  把左边任意两个和右边两个匹配(1 1 便 3 4),左边剩下两个随便换一个(1 2 换 6 6(没出现的都行)) 
	如果sum1<sum2  S和V所有匹配,V剩下的两两匹配 
	1 1 1 2 2 2 2 3 4 5 6  7
	需要处理 1  2 2 ,3 4 5 6 7 
	把左边三个和右面三个匹配(1 2 2 变为 3 4 5),右面剩下两个自己匹配 (6 7 变 6 6)
	*/
	for(auto it:mymap)
	{//遍历出现过的所有数字 
		if(it.second>=2)sum1+=it.second-2;
		else sum2+=it.second;
	}
	if(sum1>=sum2)cout<<sum1<<endl;
	else cout<<(sum1+(sum2-sum1)/2); 
	return 0;
}

D题 合并数列

 贪心 ——小的合并 (用队列模拟)

#include<bits/stdc++.h>
using namespace std;
const int MAX=2e5+10;
#define x first 
#define y second 
#define int long long
typedef pair<int,int>PII;
signed main()
{
	int n,m;
	cin>>n>>m;
	queue<int>q1;
	queue<int>q2;
	int v;
	for(int i=0;i<n;i++)
	{
		cin>>v;
		q1.push(v);
	}
	for(int i=0;i<m;i++)
	{
		cin>>v;
		q2.push(v);
	}
	int cnt=0;
	while(q1.size()&&q2.size())
	{
		int top1=q1.front(); 
		int top2=q2.front(); 
		if(top1==top2)
		{//相等都出队 
			q2.pop();
			q1.pop();
		}
	
		else if(top1<top2)
		{//top1小 所以q1前两个合并 
			q1.pop();
			q1.front()+=top1;
			cnt++;
		}
		else 
		{//top2小 所以q2前两个合并 
			q2.pop();
			q2.front()+=top2;
			cnt++;
		}
	}
	cout<<cnt<<endl;
	return 0;
}

后面期末考完补上

  • 10
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
2023第十四届蓝桥杯 C/C++ 大学生大赛 A 省赛是一个非常重要且具有挑战性的比赛。作为蓝桥杯系列赛事的一部分,这个比赛吸引了全国各地的大学生参与,旨在促进青学生计算机编程技术的提高,培养他们的创新能力和团队协作精神。 参赛者需要通过线上报名,在规定的时间内上传自己的比赛作品。比赛设置了一系列难度逐渐增加的编程题目,要求选手运用C/C++语言进行编写和实现。这些题目可能涉及算法设计、数据结构、编程基础等方面的知识,考察参赛者的编码能力、解决问题的能力以及在压力下的应变能力。 在比赛中,选手不仅需要具备扎实的编程技术,还需要在有限的时间内迅速分析问题、设计解决方案,并通过编程实现。因此,参赛者需要具备良好的逻辑思维能力、数学基础和编程实践经验。 在省赛中取得好成绩的选手将有机会晋级到全国赛,进一步与全国各地的顶尖选手一较高下,争夺更好的名次和更多的奖品。 参加蓝桥杯 C/C++ 大学生大赛不仅是一次锻炼和展示自己编程能力的机会,还能结识更多志同道合的同学和业界精英,获得丰厚的奖金和荣誉。同时,参赛经历对于大学生未来的学习和职业发展也具有积极的影响。 总之,2023第十四届蓝桥杯 C/C++ 大学生大赛 A 省赛是一个具有挑战性的比赛,参赛者需要具备扎实的编程技术和解决问题的能力。通过参与比赛,学生可以提升自己的编程能力,拓宽视野,展示个人才华,并为未来的学习和就业打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值