首页 > 编程语言 >第14届蓝桥杯C++B组省赛题解(更新中)

第14届蓝桥杯C++B组省赛题解(更新中)

时间:2023-04-23 15:33:26浏览次数:49  
标签:14 int 题解 31 mid len 金属 蓝桥 冶炼

目录

A. 日期统计

题目内容

小蓝现在有一个长度为 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 年的日期。
    对于相同的日期你只需要统计一次即可。
    本题的结果为一个整数,在提交答案时只输出这个整数,输出多余的内容将无法得分。

思路

八重循环枚举日期+set去重即可
\(Tips:\) 前4重特判2023,否则程序会跑的很慢

代码

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int n=100;
int num[N];
set<string>s;

bool check(string all)
{
	int m=stoi(all.substr(0,2));
	int d=stoi(all.substr(2,2));
	
	int mon[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
	if(m>=1&&m<=12)
	{
		if(d>=1&&d<=mon[m])
			return true;
	}
	
	return false;
}
int main()
{
	for(int i=0;i<n;i++)cin>>num[i];



	for(int a=0;a<n;a++)
	{
	
		if(num[a]!=2)continue;
		for(int b=a+1;b<n;b++)
		{
			if(num[b]!=0)continue;
			for(int c=b+1;c<n;c++)
			{
				if(num[c]!=2)continue;
				for(int d=c+1;d<n;d++)
				{	
					if(num[d]!=3)continue;
					for(int e=d+1;e<n;e++)
					{
						for(int f=e+1;f<n;f++)
						{
							for(int g=f+1;g<n;g++)
							{
								for(int h=g+1;h<n;h++)
								{
									string n1=to_string(num[e]);
									string n2=to_string(num[f]);
									string n3=to_string(num[g]);
									string n4=to_string(num[h]);
									string all=n1+n2+n3+n4;
									if(check(all))s.insert(all);
									
									
								}
							}
						}
					}
				}
			}
		}
	}	
	
	
	cout<<s.size()<<endl;
	
	return 0;
}

答案

235

B.01 串的熵

题目内容

对于一个长度 $ n $ 的 \(01\) 串 \(S = x_1x_2x_3...x_n\)。
香农信息熵的定义为:\(H(S)=-\sum_{i=1}^{n}p(x_i)log_2(p(x_i))\) ,其中 \(p(0)\), \(p(1)\) 表示在这个 \(01\) 串中 \(0\) 和 \(1\) 出现的占比。
比如,对于 \(S = 100\) 来说,信息熵 \(H(S) = - \frac{1}{3}log_2(\frac{1}{3}) - \frac{2}{3} log_2(\frac{2}{3}) = 1.3083\)。
对于一个长度为 \(23333333\) 的 \(01\) 串,如果其信息熵为 \(11625907.5798\) ,且 \(0\) 出现次数比 \(1\) 少,那么这个 \(01\) 串中 \(0\) 出现了多少次?
本题的结果为一个整数,在提交答案时只输出这个整数,输出多余的内容将无法得分。

思路

按题意模拟即可,由题意可得 \(H(S)\)的值只与 \(01\) 出现的次数有关,因为 \(0\) 出现次数比 \(1\) 少,所以可以从 \(\lfloor \frac{23333333}{2} \rfloor = 11666666\) 开始往下枚举0的个数,同时计算 \(p(0),p(1)\) 的占比,带入公式验证是否相等,注意设置误差范围去判断浮点数是否相等

代码

#include<bits/stdc++.h>
using namespace std;
const double eps=1e-4;
//#define double long double
int len;

int main()
{
	int len=23333333;
	for(int i=len/2;i>=1;i--)
	{
		double px0=1.0*i/len,px1=1.0*(len-i)/len;
		double H=-(i*px0*log2(px0)+(len-i)*px1*log2(px1));
		if(fabs(H-11625907.5798)<=eps)
		{
			cout<<i<<endl;
			return 0;
		}
	}
	
	return 0;
}

答案

11027421

C.冶炼金属

题目内容

小蓝有一个神奇的炉子用于将普通金属 \(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

思路

求最小值和最大值问题,可以利用二分答案进行判断。

  • 求最小值

    • 假设最终答案为 \(S\)
      • 因为 \(S\) 的最优性,若要求答案 \(<S\),对于每组金属 \(A\) 至少有一个不能冶炼出 \(B\) 个特殊金属
      • 若答案可以 \(>S\),则一定存在一个属性 \(V\) ,使得每组金属 \(A\) 都能冶炼出对应的 \(B\) 个特殊金属,最优解就处于可行性的分界点上
  • 求最大值与上面同理

代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int a[N],b[N];
int n;

bool check_min(int x)
{
	for(int i=0;i<n;i++)
		if(a[i]/x>b[i])return false;
	
	return true;
}

bool check_max(int x)
{
	for(int i=0;i<n;i++)
		if(a[i]/x<b[i])return false;
	
	return true;
}
int main()
{
	cin>>n;
	
	for(int i=0;i<n;i++)cin>>a[i]>>b[i];
	
	
	int l=0,r=1e9;
	
	while(l<r)
	{
		int mid=l+r>>1;
		if(check_min(mid))r=mid;
		else l=mid+1;
	}
	
	cout<<l<<' ';
	
	
	l=0,r=1e9;
	
	while(l<r)
	{
		int mid=l+r+1>>1;
		if(check_max(mid))l=mid;
		else r=mid-1;
	}
	
	cout<<l<<endl;
	
	return 0;
}

标签:14,int,题解,31,mid,len,金属,蓝桥,冶炼
From: https://www.cnblogs.com/zzmxj/p/17346697.html

相关文章

  • 关于 HBuilderX 中内置终端无法输入的问题解决
    01.先安装内置终端插件;02.打开内置终端配置文件: D:\HBuilderX\plugins\builtincef3terminal\script\main.js03.将原来的Shell.exe改成cmd.exe,重启IDE即可; ......
  • C++.14
    结构:  结构是由程序员自己设计的一种数据类型,用于描述一种事物的各项数据,由若干个不同的基础类型组成  设计:  struct结构体类型名  {    类型名成员名;    ...  };  定义:    struct结构体类型名结构体变量名; ......
  • JOISC2019 题解
    通信题还没做。JOISC19D1T1試験(Examination)双log很简单。但是单log才是这题的本质。我们进行一些补集转换。我们能算的是什么?我们能算一条边在边界上的直角边平行于坐标轴的直角三角形数点,我们能算长方形数点。我们要算1的点数,那相当于2的点数减去3的点数再加......
  • netty之TCP粘包拆包问题解决
    TCP粘包拆包问题解决什么TCP粘包和拆包问题假设客户端向服务端连续发送了两个数据包,分别用ABC和DEF来表示,那么服务端收到的数据可以分为以下三种情况:第一种情况,接收端正常收到两个数据包,即没有发生拆包和粘包的现象。第二种情况,接收端只收到一个数据包,这一个数据包中包含了发送端发......
  • 数据结构题解
    W1#怪兽训练计划1##题目描述小明有一个怪兽训练计划。初始时,怪兽充满能量,能量值为8800。如果训练怪兽,每分钟损耗能量值400;如果让怪兽休息,每分钟增加能量值200。能量的损耗和增加都是均匀变化的。小明打算让怪兽训练一分钟、休息一分钟、再训练一分钟、再休息一分钟……如此......
  • wsl2中docker启动不了的问题解决方法
    在wsl2的ubuntu系统中安装docker后,sudoservicedockerstart一直启动不起来在网上找到了解决方案https://juejin.cn/post/7197594278083919932解决方法这个错误提示通常是因为系统中使用的是经过修改的nftables,而Docker安装程序使用iptables进行NAT。为了解决这个问......
  • 题解 CF825E【Minimal Labels】
    偶然间翻到三个月前写的这个题,发现现有的题解均未给出解法的正确性证明,只是不明不白地写了一些对理解做法毫无帮助的话。我认为解法的正确性并不显然,因此这篇题解主要给出正确性证明,补上逻辑漏洞。解法与其他题解一样,即:建反图,然后跑拓扑排序,每次优先取出可以取出的编号最大的点,从......
  • 第九周题解QAQ
    A-Howmanyprimenumbers1#include<iostream>2usingnamespacestd;3boolisprime(intx)//判断素数(朴素版方法)4{5if(x<2)returnfalse;6for(inti=2;i<=x/i;i++)7if(x%i==0)returnfalse;8returntrue;9}10int......
  • CF1714D 题解
    CF1714D题解description给定黑色文本\(t\)和\(n\)个字符串\(s_1,s_2...s_n\).一次操作可以将\(t\)中与\(s_i\)相等的子串涂成红色。一个位置多次涂色后仍是红色。\(s_i\)可以使用多次。求将\(t\)涂成红色的最小次数,并输出方案。无解输出-1.\(|t|\leq100\)......
  • c++打卡训练(14)
    三色球问题:一共十二个球,红色白色都是三个,黑色有六个,摸出八个球,问有几种可能?流程图:伪代码:源代码:#include<stdio.h>intmain(){ intred,white,black; for(red=0;red<=3;red++){ for(white=0;white<=3;white++){ black=8-red-white; if(black<=6){ printf("红色:%d,......