蓝桥杯2023初赛b组 部分题目

文章介绍了四道蓝桥杯编程题目,包括日期子序列查找、字符串熵计算、金属冶炼优化和飞机降落调度,展示了C++解决方案和解题思路。
摘要由CSDN通过智能技术生成

前言

蓝桥杯的题目怎么说呢,有时候题目都不懂,心态炸裂

1.日期统计

题目来源:http://oj.ecustacm.cn/problem.php?id=2077

题意

小蓝现在有一个长度为 100 的数组,数组中的每个元素的值都在 0 到 9 的范围之内。
数组中的元素从左至右如下所示:

5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2
7 0 5 8 8 5 7 0 9 9 1 9 4 4 6 8 6 3 3 8 5 1 6 3 4 6 7 0 7 8 2 7 6 8 9 5 6 5 6 1 4 0 1
0 0 9 4 8 0 9 1 2 8 5 0 2 5 3 3

现在他想要从这个数组中寻找一些满足以下条件的子序列:
1. 子序列的长度为 8;
2. 这个子序列可以按照下标顺序组成一个 yyyymmdd 格式的日期,并且
要求这个日期是 2023 年中的某一天的日期,例如 20230902,20231223。
yyyy 表示年份,mm 表示月份,dd 表示天数,当月份或者天数的长度只有一位时需要一个前导零补充。
请你帮小蓝计算下按上述条件一共能找到多少个不同的 2023 年的日期。
对于相同的日期你只需要统计一次即可。 
本题的结果为一个整数,在提交答案时只输出这个整数,输出多余的内容将无法得分。

这道题只要能解出来,什么办法都行,只要能得到最终答案,直接输出就可以了;

#include<iostream>
using namespace std;
 
int num[100] = {5, 6, 8, 6, 9, 1, 6, 1, 2, 4, 9, 1, 9, 8, 2, 3, 6, 4, 7, 7, 5, 9, 5, 0, 3, 8, 7, 5, 8, 1, 5, 8, 6, 1, 8, 3, 0, 3, 7, 9, 2, 7, 0, 5, 8, 8, 5, 7, 0, 9, 9, 1, 9, 4, 4, 6, 8, 6, 3, 3, 8, 5, 1, 6, 3, 4, 6, 7, 0, 7, 8, 2, 7, 6, 8, 9, 5, 6, 5, 6, 1, 4, 0, 1
,0, 0, 9, 4, 8, 0, 9, 1, 2, 8, 5, 0, 2, 5, 3, 3};
 
int main() {
	int ans = 0;
	int month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	int visit[13][32] = {0}; 
	
	for (int y1 = 0; y1 < 100; y1 ++) {
		if (num[y1] == 2) {
			for (int y2 = y1 + 1; y2 < 100; y2 ++) {
				if (num[y2] == 0) {
					for (int y3 = y2 + 1; y3 < 100; y3 ++) {
						if (num[y3] == 2) {
							for (int y4 = y3 + 1; y4 < 100; y4 ++) {
								if (num[y4] == 3) {
									for (int m1 = y4 + 1; m1 < 100; m1 ++) {
										if (num[m1]<= 1) {
											for (int m2 = m1 + 1; m2 < 100; m2 ++) {
												int m = num[m1] * 10 + num[m2];
												
												if (m >= 1 && m <= 12) {
													for (int d1 = m2 + 1; d1 < 100; d1 ++) {
														if (num[d1] <= 3) {
															for (int d2 = d1 + 1; d2 < 100; d2 ++) {
																int d = num[d1] * 10 + num[d2];
																
																if (d > 0 && d <= month[m - 1] && visit[m][d] == 0) {
																	ans++;
																	visit[m][d] = 1;
																}
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	
	cout << ans;
	
	return 0;
}

以上是c++代码

2.01 串的熵

 还是和上一道题的情况相同,只要输出答案就行;

题目链接:P2078 - [蓝桥杯2023初赛] 01 串的熵 - New Online Judge

题目

对于一个长度为 n 的 01 串 S = x1x2x3...xn.
香农信息熵的定义为:
 


其中 p(0), p(1) 表示在这个 01 串中 0 和 1 出现的占比。
比如,对于S = 100 来说,信息熵 H(S ) = - 1/3 log2(1/3) - 2/3 log2(2/3) - 2/3 log2(2/3) = 1.3083。
对于一个长度为23333333 的 01 串,如果其信息熵为 11625907.5798,且 0 出现次数比 1 少,那么这个01 串中 0 出现了多少次?
本题的结果为一个整数,在提交答案时只输出这个整数,输出多余的内容将无法得分。

这道题的题意我还是有点不明白

代码如下

#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
 
int main() {
	int all = 23333333;
	
	for (int i = 0; i < 23333333; i ++) {
		double p1 = 1.0 * i / all;
		double p2 = 1.0 * (1 - p1);
		double ans = -p1 * log2(p1) * i - p2 * log2(p2) * (all - i);
		
		if (ans >= 11625907.5798 && ans <= 11625907.5799) {
			cout << i << endl;
			break;
		}
	}
	
	cout << 11027421;//0出现的个数 
	return 0;
}

3. [蓝桥杯2023初赛] 冶炼金属

题目链接:P2079 - [蓝桥杯2023初赛] 冶炼金属 - New Online Judge

题目:

小蓝有一个神奇的炉子用于将普通金属 O 冶炼成为一种特殊金属 X。
这个炉子有一个称作转换率的属性 V,V 是一个正整数,
这意味着消耗 V 个普通金属 O 恰好可以冶炼出一个特殊金属 X。
当普通金属 O 的数目不足 V 时,无法继续冶炼。
现在给出了 N 条冶炼记录,每条记录中包含两个整数 A 和 B,
这表示本次投入了 A 个普通金属O,最终冶炼出了 B 个特殊金属X。
每条记录都是独立的,这意味着上一次没消耗完的普通金属 O 不会累加到下一次的冶炼当中。
根据这 N 条冶炼记录,请你推测出转换率 V 的最小值和最大值分别可能是多少。
题目保证评测数据不存在无解的情况。

输入格式

第一行一个整数 N,表示冶炼记录的数目。
接下来输入 N 行,每行两个整数 A、B,含义如题目所述。
对于 30% 的评测用例,1 ≤ N ≤ 100。
对于 60% 的评测用例,1 ≤ N ≤ 1000。
对于 100% 的评测用例,1 ≤ N ≤ 10000,1 ≤ B ≤ A ≤ 1,000,000,000。

输出格式

输出两个整数,分别表示 V 可能的最小值和最大值,中间用空格分开。

输入样例

3
75 3
53 2
59 2

输出样例

20 25

提示

当 V = 20 时,有:⌊75 / 20⌋ = 3,⌊53 / 20⌋ = 2,⌊59 / 20⌋ = 2,可以看到符合所有冶炼记录。
当 V = 25 时,有:⌊75 / 25⌋ = 3,⌊53 / 25⌋ = 2,⌊59 / 25⌋ = 2,可以看到符合所有冶炼记录。
且再也找不到比 20 更小或者比 25 更大的符合条件的 V 值了。

代码

#include<stdio.h>
long long n,a[10005],b[10005],c[10005],d;
int main()
{
	scanf("%lld",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%lld %lld",&a[i],&b[i]);
		c[i]=a[i]/b[i];
	}
	long long min=c[0];
	for(int i=0;i<n;i++)
	{
		if(min>c[i])
		min=c[i];
	}
	for(int i=1;i<=min;i++)
	{
		int count=0;
		for(int j=0;j<n;j++)
		{
			if(b[j]*i<=a[j]&&(b[j]+1)*i>a[j])
			count++;
		}
		if(count==n)
		{
			d=i;
			break;
		}
	}
	printf("%lld %lld ",d,min);
	return 0;
}

这道题就是用暴力做出来的,也挺好理解的吧

4. [蓝桥杯2023初赛] 飞机降落

题目链接:P2080 - [蓝桥杯2023初赛] 飞机降落 - New Online Judge

题目

N 架飞机准备降落到某个只有一条跑道的机场。
其中第 i 架飞机在 Ti 时刻到达机场上空,到达时它的剩余油料还可以继续盘旋 Di 个单位时间。
即它最早可以于 Ti 时刻开始降落,最晚可以于 Ti + Di 时刻开始降落。
降落过程需要Li个单位时间。
一架飞机降落完毕时,另一架飞机可以立即在同一时刻开始降落。
但是不能在前一架飞机完成降落前开始降落。
请你判断 N 架飞机是否可以全部安全降落。

输入格式

输入包含多组数据。
第一行包含一个整数 T ,代表测试数据的组数。
对于每组数据,第一行包含一个整数 N 。
以下 N 行,每行包含三个整数:Ti,Di 和Li。
对于 30% 的数据,N ≤ 2。
对于 100% 的数据,1 ≤ T ≤ 10,1 ≤ N ≤ 10,0 ≤ Ti,Di,Li ≤ 100,000。

这道题T,N的值较小可以直接用暴力的方法,而在蓝桥杯中涉及到暴力的算法就使用DFS算法

代码如下

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 10 + 20;
struct plane{
	int t,d,l;
}p[N];
bool st[N];
int n;
bool dfs(int u,int time)
{
	if(u>=n)
	{
		return true;  //判断如果u如果大于等于n了,代表就是全部通过了,这个方案就是正确的
	}
	for(int i=0;i<n;i++)
	{
		if(!st[i])  //st[i]的初始值全部为false
		{
			st[i]=true;
			if(p[i].t+p[i].d<time)  /*如果到达时间和盘旋时间小于能够开始降落时间就表示不行,直接false,那这个方案就等于被否定了*/
			{
				st[i]=false;
				return false;
			}
			int t=max(time,p[i].t)+p[i].l;  /*求出其中的最大值赋值给t,代表下一个飞机能够开始降落的时间*/
			if(dfs(u+1,t))
			return true;  //如果都成功了就代表是true
			st[i]=false;
		}
	}
	return false;
}
void solve()
{
	cin>>n;
	for(int i = 0; i < n; i ++)
		cin >> p[i].t >> p[i].d >> p[i].l;
	if(dfs(0,0))
	{
		cout<<"YES"<<endl;
	}
	else
		cout<<"NO"<<endl;
	for(int i=0;i<n;i++)
	st[i]=false;
}  //初始化
signed main()
{
	int t=1;
	cin>>t;
	while(t--)
	solve();
}

这段代码大体去解释如上;

  • 25
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值