2021第十二届蓝桥杯国赛B组【c/c++】

2021第十二届蓝桥杯国赛B组【c/c++】

昨天刚刚打完国赛,坐着校车晃啊晃啊一路颠簸的…趁着今天脑子清醒了来一波。废话不多说,上题!
小白正在努力成长中,如有不对之处,敬请指正。

A 带宽

题目描述

小蓝家的网络带宽是 200 Mbps,请问,使用小蓝家的网络理论上每秒钟最多可以从网上下载多少 MB 的内容。

说明:这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只需要提交能输出正确答案的程序即可。

解题思路

bps指的是bit per second(比特每秒)。
B的英文全称为Byte(字节)。
换算关系:1 Byte = 8 bits。
故:200Mbps = 200/8 = 25 MB/s。

B 纯质数

题目描述

如果一个正整数只有 11和它本身两个约数,则称为一个质数(又称素数)。
前几个质数是:2,3,5,7,11,13,17,19,23,29,31,37,· · · 。
如果一个质数的所有十进制数位都是质数,我们称它为纯质数。
例如:2,3,5,7,23,37 都是纯质数,而11,13,17,19,29,31不是纯质数。当然 1,4,35也不是纯质数。
请问,在 1 到 20210605中,有多少个纯质数。

解题思路

暴力出结果!答案:1903
先判断出质数,在判断每个数位是否是质数,是就保留,不是丢弃。
上代码!

#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
vector<long long>s;
void check(long long k)
{
	int a=1,b,c,d=1;
	for(long long i=2;i<=sqrt(k);i++)
	{
		if(k%i==0)
		{
			a=0;
			break;
		}
	}
	if(a==1)
	{
		b=k;
		while(b>0)
		{
			c=b%10;
			if(c!=2&&c!=3&&c!=5&&c!=7)
			{
				d=0;
				break;
			}
			b=b/10;
		}
		if(d==1)
		{
			//cout<<k<<endl;
			s.push_back(k);
		}
	}
} 
int main()
{
	for(long long i=1;i<=20210605;i++)
	{
		check(i);
	}
	cout<<s.size();
	return 0;
}

(时间可能稍微有点久)

C 完全日期

题目描述

如果一个日期中年月日的各位数字之和是完全平方数,则称为一个完全日期。

例如:2021年6月5日的各位数字之和为2+0+2+1+6+5=16,而16是一个完全平方数,它是4的平方。所以2021年6月5日是一个完全日期。例如:2021年6月23日的各位数字之和为2+0+2+1+6+2+3=16,是一个完全平方数。所以2021年6月23日也是一个完全日期。

请问,从2001年1月1日到2021年12月31日中,一共有多少个完全日期?

解题思路

暴力出结果!答案:977
先判断年份是否是闰年,在依次遍历月份和日期,判断各位数字之和是否是完全平方数。
上代码!

#include <iostream>
#include <math.h>
using namespace std;
bool judge(long long k)
{
	double t;
	t=sqrt(((double)k));
	if(((t*t))==((double)k))
	{
		return true;
	}
	return false;
}
int main()
{
	long long b[21]={3,4,5,6,7,8,9,10,11,3,4,5,6,7,8,9,10,11,12,4,5};//年 
	long long d[12]={1,2,3,4,5,6,7,8,9,1,2,3};//月 
	long long c[31]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,10,2,3,4,5,6,7,8,9,10,11,3,4};//日 
	long long a[12]={31,28,31,30,31,30,31,31,30,31,30,31};
	long long i,j,k;
	long long sum,count=0;
	for(i=2001;i<=2021;i++)
	{
		sum=0;
		if((i%4==0&&i%100!=0)||i%400==0)
		{
			a[1]=29;
		}
		sum=sum+b[i-2001];
		for(j=0;j<12;j++)
		{
			sum=sum+d[j];
			for(k=0;k<a[j];k++)
			{
				if(judge(sum+c[k]))
				{
					count++;
				}
			}
			sum=sum-d[j];
		}
		a[1]=28;
	}
	cout<<count;
	return 0;
} 

D 最小权值

题目描述

对于一棵有根二叉树 T,小蓝定义这棵树中结点的权值 W(T)如下:

空子树的权值为 0。

如果一个结点 v 有左子树 L, 右子树 R,分别有 C(L)和 C®个结点,则 W(v) = 1 + 2W(L) + 3W® + (C(L))^2 C®。

树的权值定义为树的根结点的权值。

小蓝想知道,对于一棵有 2021个结点的二叉树,树的权值最小可能是多少。

解题思路

太难了,还在努力中。
记得比赛时萌生过一个很天真的想法,当没有右子树时,那么W(v) = 1 + 2W(L) + 3W® + (C(L))^2 C®可以演变为W(v) = 1 + 2W(L),那么无限寻找下去2021个结点的最小权值可能是2021哈哈哈哈哈。这仅仅是个天真的想法,好啦,等我翻书再看看先吧。

E 大写

题目描述

给定一个只包含大写字母和小写字母的字符串,请将其中所有的小写字母转换成大写字母后将字符串输出。

输入格式

输入一行包含一个字符串。

输出格式

输出转换成大写后的字符串。

样例

输入#1

LanQiao

输出#1

LanQiao
说明/提示

对于所有评测用例,字符串的长度不超过 100。

解题思路

上代码!

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s;
	cin>>s;
	for(int i=0;i<s.size();i++)
	{
		if(s[i]>=97&&s[i]<=122)
		{
			s[i]=s[i]-32;
		}
	}
	cout<<s;
	return 0;
}

F 123

题目描述

小蓝发现了一个有趣的数列,这个数列的前几项如下:

1, 1, 2, 1, 2, 3, 1, 2, 3, 4, …

小蓝发现,这个数列前 11项是整数 1,接下来 2 项是整数 1 至 2,接下来 3 项是整数 1 至 3,接下来 4项是整数 1 至 4,依次类推。

小蓝想知道,这个数列中,连续一段的和是多少。

输入格式

在这里插入图片描述

输出格式

输出 T 行,每行包含一个整数表示对应询问的答案。

样例

输入#1

3
1 1
1 3
5 8

输出#1

1
4
8
说明/提示

在这里插入图片描述

解题思路

先说明该代码仅仅能通过了70%的样例,害!超时了,哭泣。
还在努力突破中。。。

想法是这样的,先判断起始数字位置和末尾数字的位置属于第几项。
这里用到了等差数列求和的计算公式。
在这里插入图片描述
判断出项位,就可以从第 i 项到第 j 项求和了。
上代码!

#include <iostream>
#include <math.h>
using namespace std;
struct A
{
	long long l;
	long long r;
};
long long judge(long long k)
{//判断属于第几项 
	long long t;
	t=sqrt(k);
	while((t*t+t)/2<k)
	{
		t++;
	}
	return t;
}
long long check(long long x,long long y)
{
	long long sum=0;
	long long n1,n2;
	long long a,b;
	n1=judge(x);//首项和尾项 
	n2=judge(y);
	a=x-((n1-1)*(n1-1)+(n1-1))/2;
	b=y-((n2-1)*(n2-1)+(n2-1))/2;
	//计算首尾项的和 
	if(n1==n2)
	{//如果首项和尾项属于同一项内,用等差数列求和公式计算 
		sum=sum+(b*b+b)/2-((a-1)*(a-1)+(a-1))/2;
	}
	else
	{
		sum=sum+(n1*n1+n1)/2-((a-1)*(a-1)+(a-1))/2;
		sum=sum+(b*b+b)/2;
	}
	for(long long i=n1+1;i<n2;i++)
	{//从首项后的第二项开始计算 
		sum=sum+(i*i+i)/2;
	}
	return sum;
}
int main()
{
	long long t;
	cin>>t;
	A a[t];
	for(long long i=0;i<t;i++)
	{
		cin>>a[i].l>>a[i].r;
	}
	
	for(long long i=0;i<t;i++)
	{
		cout<<check(a[i].l,a[i].r)<<endl;
	}
	return 0;
}

G 异或变换

题目描述

在这里插入图片描述

输入格式

输入的第一行包含两个整数 n, t,分别表示 01 串的长度和变换的次数。

第二行包含一个长度为 nn的 01 串。

输出格式

输出一行包含一个 01 串,为变换后的串。

样例

输入#1

5 3
10110

输出#1

11010
说明/提示

在这里插入图片描述

解题思路

先说明该代码仅仅能通过了60%的样例,害!我努力了还是超时了。。。
没啥思路,就一位一位的异或就好。
估计就是没有优化所以宕机了。。。
上代码!

#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main()
{
	long long n,t;
	cin>>n>>t;
	char s[10000],a[10000];
	cin>>s;
	for(long long i=0;i<t;i++)
	{
		a[0]=s[0];
		for(long long j=1;j<n;j++)
		{
			if((s[j]^s[j-1])==0)
			{
				a[j]='0';
			}
			else
			{
				a[j]='1';
			}
		}
		strcpy(s,a);
	}
	cout<<s;
	return 0;
}

H 二进制问题

题目描述

小蓝最近在学习二进制。他想知道 1 到 N 中有多少个数满足其二进制表示中恰好有 K个 1。你能帮助他吗?

输入格式

输入一行包含两个整数 N 和 K。

输出格式

输出一个整数表示答案。

样例

输入#1

7 2

输出#1

3
说明/提示

在这里插入图片描述

解题思路

这题我只会暴力求解,所以还是超时了,好像只能通过30%的样例,见笑了。

有过一个可爱的想法:用排列组合问题, 对于1 到 N 个数,先找出二进制表示所需的最大位数,记为T,则相当于从T个位置中选择K个位置放1。

好了,这个可爱想法还未实现,没有代码。
只有暴力求解代码:

#include <iostream>
#include <math.h>
using namespace std;
long long check(long long x,long long y)
{
	long long k;
	long long count=0; 
	while(x>0)
	{
		k=x%2;
		if(k==1)
		{
			count++;
			if(count>y)
			{
				return 0;
			}
		}
		x=x/2;
	}
	if(count==y)
	{
		return 1;
	}
	else{
		return 0;
	}
}
int main()
{
	long long n,k;
	long long sum=0;
	cin>>n>>k;
	for(long long i=1;i<=n;i++)
	{
		sum=sum+check(i,k);
	}
	cout<<sum;
	return 0;
} 

I 翻转括号序列

题目描述

在这里插入图片描述

输入格式

在这里插入图片描述

输出格式

在这里插入图片描述

样例

输入#1

7 5
((())()
2 3
2 2
1 3 5
2 3
2 1

输出#1

4
7
0
0
说明/提示

在这里插入图片描述

解题思路

没有思路。。。

J 异或三角

题目描述

在这里插入图片描述

输入格式

在这里插入图片描述

输出格式

在这里插入图片描述

样例

输入#1

2
6
114514

输出#1

6
11223848130
说明/提示

在这里插入图片描述

解题思路

依旧没有思路。。。

OK!以上就是小白第一次蓝桥国赛冒险的全部了,还有很多需要努力的地方,我会继续加油的!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值