C++蓝桥杯填空题(必拿分)

片头

嗨~小伙伴们,今天咱们来看看填空题,蓝桥杯竞赛体型分为填空题和编程题。咱们先把填空题做对了,越往后面越有信心,对不对~


第1题  握手问题

 分析这道题,我们有2种解题思路:

①编号1~7的人彼此之间不握手,但是这7个人与除这7人以外的所有人握手,剩下的所有人都与除自己以外的所有人进行握手(有且仅有1次)

②计算50个人彼此握手的次数-7个人相互握手的次数

 方法一:

//①握手问题

//方法一
int main1() {
	int count = 0;
	for (int i = 1; i <= 50; i++) {
		for (int j = i + 1; j <= 50; j++) {
			//i和j表示我枚举的2个人,当2个人编号中至少1个人大于7时,才会握手
			if (i <= 7 && j <= 7) continue;
			else count++;
		}
	}

	cout << count << endl; //1204
	return 0;
}

方法二:采用等差数列求和

比如:这里有3个人,3号,2号,1号。

3号可以和2号握手,3号也可以和1号握手。2号可以和1号握手,总共2+1=3次。这时,如果来了4号,4号和3号握手,4号和2号握手,4号和1号握手,又增加了3次,总共3+2+1=6次。

那么,如果有50个人,

50号可以握49次,

49号可以握48次,

48号可以握47次,

........

3号可以握2次,

2号可以握1次,

1号可以握0次。

总共 49+48+47+46+.....+3+2+1+0 = (49+0)×50÷2 = n*(n-1)/2

代码如下:

//等差数列
int F(int n) {
	return n * (n - 1) / 2;
}

int main() {
	int ret = F(50) - F(7);
	cout << ret << endl;			//1204
	return 0;
}

第2题  门牌制作

 我们可以先定义一个for循环,遍历从1~2020之间的所有数字,统计每个数字中,"2"的出现次数。

代码如下:

//②门牌制作
int main() {
	int count = 0;	//计数器,用于统计字符"2"的个数

	//遍历从1~2020的所有门牌号
	for (int i = 1; i <= 2020; i++) {
		int x = i;

		//逐个提取数字并检查是否为"2"
		while (x > 0) {
			if (x % 10 == 2) count++;	//如果当前数字为"2",计数器+1
			x = x / 10;					//去掉最后一位
		}
	}
	cout << count << endl;  //624

	return 0;
}

第3题  幸运数

这道题,让我们判断这个数字是否为幸运数。幸运数——一个数含有偶数个数位,如果前面一半的数位之和等于后面一半的数位之和,那么这个数就是幸运数。题目要求从1~100000000之间有多少这样的数字。

首先,我们可以将1~100000000之间,排除非偶数个位的数。怎么排除呢?可以先将当前这个数字转换为字符串,求字符串的长度。如果长度为奇数,直接跳过当前循环,继续下一个循环。

如果长度为偶数,那么我们需要判断前一半的数是否等于后面一半的数,如果相等,则为幸运数。

代码如下:

//③幸运数-循环

int main() {
	int count = 0;
	for (int i = 1; i <= 100000000; i++) {
		string x = to_string(i);   //先将数字转换为字符串
		int len = x.size();        //求字符串的长度

		if (len % 2 == 1) continue; //如果这个长度为奇数,说明当前这个数非偶数个位

		int sum1 = 0, sum2 = 0;     //sum1表示前半部分的和,sum2表示后半部分的和
        
		for (int j = 0; j < len; j++) {
			if (j < len / 2)  sum1 += x[j] - '0';
			else sum2 += x[j] - '0';
		}
		if (sum1 == sum2)  count++;
	}

	cout << count << endl;		//4430091
	return 0;
}

第4题  九进制转十进制

 对于这道题,我们可以使用python来做,因为是填空题,所以不需要我们写出解答过程,只需填上最后的答案即可。

print(int('2022',9))

运行结果为:

1478

那么将九进制转换为十进制我们知晓了,怎么将十进制转换为二进制呢?

先来一个套公式:

n = 2022
print(format(n,"b")) #"b"代表的是: 以二进制的形式打印

运行结果为:

11111100110

 我们再来自主实现:

s1 = ""
n = 2022

while(n > 0):
   r = n % 2
   s1 = str(r) + s1
   n = n // 2

print(s1)

同理,将十进制转换为九进制就是依葫芦画瓢啦~

s = ""
num = 1478

while(num > 0):
   r = num % 9       //转换为九进制
   s = str(r) + s
   num = num // 9

print(s)

运行结果如下:

2022


 第5题  艺术与篮球

 ①对于这道题,我们可以先用数组cnt[10]把汉字零~九的笔画数存起来;定义数组month[13],用来存放每个月的天数(多开1个空间,方便计算);定义判断是否为闰年的函数bool is_leap(int y),如果当前年份为闰年,返回true,否则返回false

//从1月~12月,每个月的天数
	int  month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };

    int cnt[10];
//从零~九,每个汉字的笔画数
	cnt[0] = 13, cnt[1] = 1, cnt[2] = 2, cnt[3] = 3, cnt[4] = 5;
	cnt[5] = 4, cnt[6] = 4, cnt[7] = 2, cnt[8] = 2, cnt[9] = 2;

//判断闰年
bool is_leap(int y) {
	if (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0))  return true;
	return false;
}

②定义3个变量y、m、d,分别表示年、月、日。年的范围是从2000年~2024年。因此,最外层的for循环从2000开始,到2024结束。

	int res = 0;//统计可以练篮球的天数

	int y, m, d;//分别表示年、月、日

	//枚举年份
	for (y = 2000; y <= 2024; y++) {

	}

③接着需要判断月份的范围,题目已知,在2024年,月份只能到4月,因此,当y==2024时,月份的范围:1~4,上限为4;除此之外,月份的范围:1~12,上限为12。那么我们需要定义三元运算符,如果此时在2024年,那么月份的范上限为4,否则月份的上限为12。

int up1 = (y == 2024) ? 4 : 12;

④判断完月份取值范围后,咱们需要判断当前年份是否为闰年,如果此时为闰年,那么month数组里面表示2月份的天数修改为29天;如果不是闰年,2月份的天数仍然为28天。

//判断闰年
bool is_leap(int y) {
	if (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0))  return true;
	return false;
}


if (is_leap(y)) month[2] = 29;
else month[2] = 28;

⑤根据前面月份的上限,我们开始循环遍历月份,题目已知:当年份为2024年并且月份为4月时,日期只能到13号,范围:1~13;除此以外,每个月的日期都可以用month数组里面的值来表示。我们可以用三元运算符来判断,当 y==2024 && m == 4 时,日期的上限为13;否则日期上限为month[m](m表示当前的月份)

//枚举年份
for (y = 2000; y <= 2024; y++) {
	int up1 = (y == 2024) ? 4 : 12;
	if (is_leap(y)) month[2] = 29;
	else month[2] = 28;

	//枚举月份
	for (m = 1; m <= up1; m++) {
		int up2 = (y == 2024 && m == 4) ? 13 : month[m];
	}
}

⑥根据前面日期的上限,我们开始循环遍历日期,判断每一个日期是否符合笔画数>50。如果符合,计数器+1。

	int res = 0;//统计可以练篮球的天数

	int y, m, d;//分别表示年、月、日

	//枚举年份
	for (y = 2000; y <= 2024; y++) {
		int up1 = (y == 2024) ? 4 : 12;
		if (is_leap(y)) month[2] = 29;
		else month[2] = 28;

		//枚举月份
		for (m = 1; m <= up1; m++) {
			int up2 = (y == 2024 && m == 4) ? 13 : month[m];
			//枚举日期
			for (d = 1; d <= up2; d++) {
				res += Func1(y, m, d);
			}
		}
	}

⑦在main函数外面定义统计汉字笔画数的函数。我们可以把传递过来的年、月、日都转换为字符串,利用to_string函数。如果月份<10,那么需要加上字符'0',再和前面的年份拼接;如果日期<10,需要加上字符'0',再和前面的年份、月份进行拼接。拼接完成后,使用范围for循环遍历字符串中每一个元素,计算每一个元素在cnt数组中的映射位置对应的值。用变量res统计每一个字符串类型的日期总笔画数。返回总笔画数>50的结果。如果总笔画数>50,返回1;否则返回0。

int Func1(int y, int m, int d) {
	string s = to_string(y);		//将年份转换为字符串
	if (m < 10) s += '0';
	s += to_string(m);				//将月份转换为字符串并且和年份拼接
	if (d < 10) s += '0';
	s += to_string(d);				//将日期转换为字符串并且和年份、月份拼接

	int sum = 0;
	for (auto e : s)				//遍历s字符串中每一个元素
									//找到cnt数组中的映射位置的值
	{
		sum += cnt[e - '0'];
	}

	return sum > 50;				//返回结果
									//如果大于50,return 1;否则 return 0;
}

欧克欧克,这道题整体代码如下:

//⑤艺术与篮球

int cnt[10];

//判断闰年
bool is_leap(int y) {
	if (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0))  return true;
	return false;
}

int Func1(int y, int m, int d) {
	string s = to_string(y);		//将年份转换为字符串
	if (m < 10) s += '0';
	s += to_string(m);				//将月份转换为字符串并且和年份拼接
	if (d < 10) s += '0';
	s += to_string(d);				//将日期转换为字符串并且和年份、月份拼接

	int sum = 0;
	for (auto e : s)				//遍历s字符串中每一个元素
									//找到cnt数组中的映射位置的值
	{
		sum += cnt[e - '0'];
	}

	return sum > 50;				//返回结果
									//如果大于50,return 1;否则 return 0;
}


int main() {
	//从1月~12月,每个月的天数
	int  month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };

	//从零~九,每个汉字的笔画数
	cnt[0] = 13, cnt[1] = 1, cnt[2] = 2, cnt[3] = 3, cnt[4] = 5;
	cnt[5] = 4, cnt[6] = 4, cnt[7] = 2, cnt[8] = 2, cnt[9] = 2;

	int res = 0;//统计可以练篮球的天数

	int y, m, d;//分别表示年、月、日

	//枚举年份
	for (y = 2000; y <= 2024; y++) {
		int up1 = (y == 2024) ? 4 : 12;
		if (is_leap(y)) month[2] = 29;
		else month[2] = 28;

		//枚举月份
		for (m = 1; m <= up1; m++) {
			int up2 = (y == 2024 && m == 4) ? 13 : month[m];
			//枚举日期
			for (d = 1; d <= up2; d++) {
				res += Func1(y, m, d);
			}
		}
	}

	cout << res << endl;  //3228

	return 0;
}

 运行结果为:


第6题  求和

这道题,我们可以运用高斯定理:(首项+末项)×项数÷2

#include <iostream>
using namespace std;
long long Func(long long n) {
	return n * (n + 1) / 2;
}

int main() {
	long long  ret = Func(20230408);
	cout << ret << endl;

	return 0;
}

注意:这里的数据类型必须是长整型long long,如果为int,会溢出! 


第7题  3个1

 这道题,涉及到位运算相关知识。

我们从1开始遍历,终止条件未知,判断完这个数自动+1。

怎么判断1个数转换为二进制后,有3个数位为1呢?可以采用while循环,使这个数和1进行按位与&操作。按位与:两者相同为1,两者相异为0。

从右往左依次和1进行按位与&操作 ----> 判断完最后1个数位,再进行右移>>操作,判断倒数第2个数位,再判断倒数第3个数位.......,直到这个数为0,结束循环。

如果和1进行按位与&操作得出来的结果为1,计数器+1。

定义变量ans,当计数器恰好等于3时,ans++; 当ans恰好等于23时,将答案输出即可。

int main() {
	int ans = 0;

	for (int i = 1; ; i++)  //起始条件: i = 1,从1开始往后遍历
							//更新条件: 每判断完1个数,自动往后+1
	{
		int x = i;			//将i的值赋给临时变量x
		int count = 0;		//count统计当前这个数的二进制中,出现"1"的次数

		while (x > 0)		//当x为0时,结束循环
		{
			if (x & 1)		//将这个数和1进行按位与&操作
			{
				count++;	//假设结果为1,count自增1
			}
			x = x >> 1;		//每判断完最后1位,向右移,将最后1个数位覆盖掉
		}
		if (count == 3)  ans++;  //如果count的值为3,ans++
		if (ans == 23)			 //如果此时ans为23,
								 //说明我们已经找到了第23个满足: 
								 //数转换为二进制之后,恰好有3个数位为"1"
		{
			cout << i << endl;	 //将这个数输出
			break;				 //终止循环
		}
	}

	return 0;
}

第8题  美丽的2024

这道题和刚刚那道题差不多,只不过是统计二进制中"1"的个数。 

代码如下:

//⑧美丽的2024-位运算
int main() {
	int n = 2024;
	int temp = n;		//将n的值赋给临时变量

	int cnt = 0;		//统计二进制中,出现"1"的个数
	while (temp > 0)	//当temp==0时,终止循环
	{
		if (temp & 1) cnt++;	//如果当前数位和1进行按位与&操作后,结果为1,cnt++;
		temp = temp >> 1;		//每操作完最后1个数位,向右移,将最后1个数位覆盖掉
	}
	cout << cnt << endl;	    //7 --> 11111101000

	return 0;
}

第9题  跑步

诶,这道题,乍一看,感觉不复杂,咱们一起来看看~

 我们首先定义月份数组month[13],用来统计每个月的天数。

外层for循环,表示月份范围,从1月到12月,内层for循环,表示日期,从1到month[i]。如果日期为1号、11号、21号、31号,那么计数器+1。

如何统计周六、周天呢?很简单,定义变量week,初始值为6,表示周六,如果 (week+1)%7==0,表示周天。那么,如果week==6或者week==0,计数器也要+1。

代码如下:

int main() {
	int month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	int w = 6;	//今天是星期六

	int cnt = 0;
	//枚举月
	for (int i = 1; i <= 12; i++) {
		//枚举日期
		for (int j = 1; j <= month[i]; j++) {
			//判断是否符合题目要求
			if (w == 6 || w == 0 || j == 1 || j == 11 || j == 21 || j == 31) {
				cnt++;
			}
			w = (w + 1) % 7; //如果周天+1,即周一,因此这里其实是循环的
		}
	}
	cout << cnt << endl;
	return 0;
}

片尾

今天我们学习了C++蓝桥杯填空题相关知识点,希望对友友们有所帮助!!!

求点赞收藏加关注!!!

谢谢大家!!!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值