2020蓝桥杯省赛C/C++第二场B组(2020.10.17)反思

本文解析了优快云竞赛中的填空题,包括门牌制作、既约分数等数学问题,以及跑步锻炼、成绩分析等实际应用问题。通过代码示例详细解答了各个题目。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不太熟悉优快云的markdown编辑器,格式不对请见谅。

题目:来自CMDN

​ https://blog.youkuaiyun.com/qq_43312718/article/details/109133992(B组没有荒岛探测

​ https://blog.youkuaiyun.com/qq_924485343/article/details/109135232

环境:Dev-cpp5.11

解题者不会C++ :^(

填空

1.门牌制作

【问题描述】

小蓝要为一条街的住户制作门牌号。这条街一共有2020 位住户,门牌号从1 到2020 编号。小蓝制作门牌的方法是先制作0 到9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌1017 需要依次粘贴字符1、0、1、7,即需要1 个字符0,2 个字符1,1 个字符7。请问要制作所有的1 到2020 号门牌,总共需要多少个字符2?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

解:624

#include<stdio.h>
int main(void)
{
	int num = 0;
	for (int i=1; i<=2020; i++) {
		if (i%10 == 2) num++;
		if (i/10%10 == 2) num++;
		if (i/100%10 == 2) num++;
		if (i/1000%10 == 2) num++;
	}
	printf("%d",num);
	return 0;
} 

2.既约分数

【问题描述】

如果一个分数的分子和分母的最大公约数是1,这个分数称为既约分数。例如,3/4 , 5/2 , 1/8 , 7/1都是既约分数。请问,有多少个既约分数,分子和分母都是1 到2020 之间的整数(包括1和2020)?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

解:2481215

#include<stdio.h>
int gongyue(int a, int b);

int main(void)
{
	int num=0;
	for (int i=1; i<=2020; i++) {
        for (int j=1; j<=2020; j++) {
        	if (gongyue(i, j) == 1)
                num++;
        }
    }
    printf("%d",num);
    return 0;
}

int gongyue(int i, int j)
{
	int temp=0;
	while (i%j != 0) {
        temp = i % j;
        i = j;
        j = temp;
    }
    return j;
}

3.蛇形填数

【问题描述】

如下图所示,小明用从1 开始的正整数“蛇形”填充无限大的矩阵。
蛇形填数
容易看出矩阵第二行第二列中的数是5。请你计算矩阵中第20 行第20 列的数是多少?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

解:761

分析:(这是舍友Lee的解法,不用编程,比我的更简单)

(1) 1 2 6 7 15 ……

(2) 3 5 8 14 ……

(3) 4 9 13 ……

(4) 10 12 ……

(5) 11 ……


(1) (1, 1) —> 1

(3) (2, 2) —> 5

(5) (3, 3) —> 13

……

(39——第20个奇数) (20, 20) —> 761

当然,也可以用编程或者Excel解题。

4.跑步锻炼

img

解:8879000

#include<stdio.h>

int MONTH[13] = {0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int pingrun(int year)
{
    if (year%400==0 || (year%4==0 && year%100!=0))
        MONTH[2] = 29;
    else
        MONTH[2] = 28;
    return 0;
}

int run(int day, int wek)
{
	if(day==1 && wek!=1) return 2000;
	if(day!=1 && wek==1) return 2000;
	if(day==1 && wek==1) return 2000;
	return 1000;	
}

int main(void)
{
    int year=2000;
	int month=1;
	int day=1;
	int wek=6;
	int mi=2000;
    while (year!=2020 || month!=10 || day!=1) {
        pingrun(year);
        day++;
        wek = (wek+1) % 7;
        if (day > MONTH[month]) {
            day = 1;
            month++;
            if (month > 12) {
                month = 1;
                year++;
            }
        }
        mi = mi+run(day, wek);
    }
    printf("%d\t%d.%d.%d", mi, year, month, day);
    return 0;
}

5.七段码

【问题描述】

小蓝要用七段码数码管来表示一种特殊的文字。
七段码上图给出了七段码数码管的一个图示,数码管中一共有7 段可以发光的二极管,分别标记为a, b, c, d, e, f, g。小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。
例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。
例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

答案:80

我的解法:分别讨论a, b, c, d, e, f, g,这题我的做法麻烦而且我做错了OTZ

大佬解法:https://blog.youkuaiyun.com/hesorchen/article/details/109135518

#include <bits/stdc++.h>
using namespace std;

int head[100];
int ct = 1;
struct node
{
    int v, next;
} e[100];

void add(int u, int v)
{
    e[ct].v = v;
    e[ct].next = head[u];
    head[u] = ct++;
    swap(u, v);
    e[ct].v = v;
    e[ct].next = head[u];
    head[u] = ct++;
}

void init() //建图
{
    add(1, 2), add(1, 6), add(2, 7), add(2, 3), add(3, 4);
    add(3, 7), add(4, 5), add(5, 6), add(5, 7), add(6, 7);
}

int ans[100], vis[100];
set<int> st;

void save(int ct)
{
    int anss[10];
    for (int i = 1; i <= ct; i++)
        anss[i] = ans[i];
    sort(anss + 1, anss + 1 + ct);
    int res = 0;
    for (int i = 1; i <= ct; i++)
        res = res * 10 + anss[i];
    st.insert(res);
}
void dfs(int now, int all, int ct)
{
    ans[ct] = now;
    if (all == ct) //如果找到了大小为all的连通块 保存答案
    {
        save(all);
        return;
    }
    for (int i = head[now]; i; i = e[i].next)
    {
        int v = e[i].v;
        if (!vis[v])
        {
            vis[v] = 1;
            dfs(v, all, ct + 1);
            vis[v] = 0;
        }
    }
}
int main()
{
    init();
    for (int i = 1; i <= 7; i++)     //起点
        for (int j = 1; j <= 7; j++) //连通块大小
        {
            vis[i] = 1;
            dfs(i, j, 1);
            vis[i] = 0;
        }
    cout << st.size() << endl;
    return 0;
}

6.平面分割(记不清有没有了)

【问题描述】

20 个圆和20 条直线最多能把平面分成多少个部分?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

?????????????小问号你是否有许多的朋友???????????????????

  1. ​ 20条直线

2
2
3
4
……
20=211

  1. ​ 20个圆

1个圆   2个部分     2=2
2个圆   4个部分 4=2+2*1
3个圆   8个部分 8=2+2*1+2*2
4个圆   14个部分 14=2+2*1+2*2+2*3
……
10个圆  92个部分 92=2+2*1+……+2*9
20个圆 382=2+2*(1+2+3+4+...+19)=382

好像我理解错了,不是20个圆和20个直线分别能把平面最多分成多少部分。而是一共分成多少部分。(啊这)

编程

7.成绩分析

网上找到的题不对,记忆里大约是:

【问题描述】

小蓝给学生们组织了一场考试,卷面总分为100 分,每个学生的得分都是一个0 到100 的整数。请计算这次考试的及格率和优秀率。

及格 >=60

优秀 >=85

【输入格式】

输入的第一行包含一个整数n,表示考试人数。
接下来n 行,每行包含一个0 至100 的整数,表示一个学生的得分。

【输出格式】

输出二行。
第一行及格率。
第二行优秀率。
四舍五入保留整数。

【样例输入】

记不清具体数了,大概是7和7个数。

7
80
92
56
74
88
99
100
0
【样例输出】
72%
43%
【评测用例规模与约定】

对于50% 的评测用例, 1 ≤ n ≤ 100。
对于所有评测用例,1 ≤ n ≤10000。

解:

#include<stdio.h>
int main(void)
{
	long n=0;
	int chengji=0;
	long jige=0;
	long youxiou=0;
	
	scanf("%ld",&n);
	for (int i=0; i<n; i++) {
		scanf("%d",&chengji);
		if(chengji>=85)	youxiou++;
		if(chengji>=60)	jige++;
	}
	if (jige*1000/n%10 >= 5) {
		printf("%d%%\n", jige*100/n + 1);
	}else{
		printf("%d%%\n", jige*100/n);
	}
	if (youxiou*1000/n%10 >= 5) {
		printf("%d%%\n", youxiou*100/n + 1);
	}else{
		printf("%d%%\n", youxiou*100/n);
	}
	return 0;
}

8.回文日期

【问题描述】

2020 年春节期间,有一个特殊的日期引起了大家的注意:2020年2月2日。因为如果将这个日期按“yyyymmdd” 的格式写成一个8 位数是20200202
恰好是一个回文数。我们称这样的日期是回文日期。
有人表示20200202 是“千年一遇” 的特殊日子。对此小明很不认同,因为不到2年之后就是下一个回文日期:20211202 即2021年12月2日。
也有人表示20200202 并不仅仅是一个回文日期,还是一个ABABBABA型的回文日期。对此小明也不认同,因为大约100 年后就能遇到下一个ABABBABA 型的回文日期:21211212 即2121 年12 月12 日。算不上“千年一遇”,顶多算“千年两遇”。
给定一个8 位数的日期,请你计算该日期之后下一个回文日期和下一个ABABBABA型的回文日期各是哪一天。

【输入格式】

输入包含一个八位整数N,表示日期。

【输出格式】

输出两行,每行1 个八位数。第一行表示下一个回文日期,第二行表示下
一个ABABBABA 型的回文日期。

【样例输入】
20200202
【样例输出】
20211202
21211212
【评测用例规模与约定】

对于所有评测用例,10000101 ≤ N ≤ 89991231,保证N 是一个合法日期的8位数表示。

解:(一力降十惠,直接爆破)

原谅我的懒惰,大致思路是列出输入日期后符合日期的数

xxxx . xx . xx

1000~8999 1~12 1~31

​ 或

​ 1~30

​ 或

​ 1~28、29

放入数组a[8]

判断回文数:
a[0]==a[7]
a[1]==a[6]
a[2]==a[5]
a[3]==a[4]
在回文数的基础上,判断ababbaba:
a[0]==a[2]
&&
a[1]==a[3]
分别输出第一个:)

试题H: 子串分值

时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分

【问题描述】

对于一个字符串S,我们定义S 的分值 f(S) 为S中恰好出现一次的字符个数。例如f (”aba”) = 1,f (”abc”) = 3, f (”aaa”) = 0。
现在给定一个字符串S[0…n-1](长度为n),请你计算对于所有S的非空子串S[i…j](0 ≤ i ≤ j < n), f (S[i… j]) 的和是多少。

【输入格式】

输入一行包含一个由小写字母组成的字符串S。

【输出格式】

输出一个整数表示答案。

【样例输入】
ababc
1
【样例输出】
21
1
【样例说明】

子串f值:

a     1
ab    2
aba   1
abab  0
ababc 1
 b    1
 ba   2
 bab  1
 babc 2
  a   1
  ab  2
  abc 3
   b  1
   bc 2
    c 1
123456789101112131415
【评测用例规模与约定】

对于20% 的评测用例,1 ≤ n ≤ 10;
对于40% 的评测用例,1 ≤ n ≤ 100;
对于50% 的评测用例,1 ≤ n ≤ 1000;
对于60% 的评测用例,1 ≤ n ≤ 10000;
对于所有评测用例,1 ≤ n ≤ 100000。

解:赛时没做完,赛后杂事太多,虽有思路了,然失去了解题的欲望…… OTZ

附大佬解法:https://blog.youkuaiyun.com/qq_44378358/article/details/109134500

9. 25分大题

我是按顺序做的,做完回文日期后比赛时间内就不够了,没有看后面的题,下面是网上搜集的题,木的答案。
顺便吐槽一下优快云的markdown编辑器和Typora的效果不太一样,我一开始是想直接导入的……

试题I: 荒岛探测

时间限制: 1.0s 内存限制: 256.0MB 本题总分:25 分

【问题描述】

科学家小蓝来到了一个荒岛,准备对这个荒岛进行探测考察。小蓝使用了一个超声定位设备来对自己进行定位。为了使用这个设备,小蓝需要在不同的点分别安装一个固定的发射器和一个固定的接收器。小蓝手中还有一个移动设备。定位设备需要从发射器发射一个信号到移动设备,移动设备收到后马上转发,最后由接收器接收,根据这些设备之间传递的时间差就能计算出移动设备距离发射器和接收器的两个距离,从而实现定位。
小蓝在两个位置已经安装了发射器和接收器,其中发射器安装在坐标( x A , y A ) (x_A, y_A)(x**A​,y**A​),接收器安装在坐标( x B , y B ) (x_B, y_B)(x**B​,y**B​)。小蓝的发射器和接收器可能在岛上,也可能不在岛上。小蓝的定位设备设计有些缺陷,当发射器到移动设备的距离加上移动设备到接收器的距离之和大于L 时,定位设备工作不正常。当和小于等于L 时,定位设备工作正常。为了安全,小蓝只在定位设备工作正常的区域探测考察。
已知荒岛是一个三角形,三个顶点的坐标分别为( x 1 , y 1 ) (x_1, y_1)(x1​,y1​), ( x 2 , y 2 ) (x_2, y_2)(x2​,y2​), ( x 3 , y 3 ) (x_3, y_3)(x3​,y3​)。
请计算,小蓝在荒岛上可以探测到的面积有多大?

【输入格式】

输入的第一行包含五个整数,分别为x A , y A , x B , y B , L x_A, y_A, x_B, y_B, Lx**A,y**A,x**B,y**B,L
第二行包含六个整数,分别为x 1 , y 1 , x 2 , y 2 , x 3 , y 3 x_1, y_1, x_2, y_2, x_3, y_3x1​,y1​,x2​,y2​,x3​,y3​。

【输出格式】

输出一行,包含一个实数,四舍五入保留2位小数,表示答案。
考虑到计算中的误差,只要你的输出与参考输出相差不超过0.01即可得分。

【样例输入】
10 6 4 12 12
0 2 13 2 13 15
12
【样例输出】
39.99
1
【样例说明】

当输出为39.98、39.99或40.00时可以得分。

【评测用例规模与约定】

漏掉了没保存上

试题J

惊喜! 发现少保存了一个题。。。从同学那里找到的Java B组的填空题,题面基本一样,先放上来。

时间限制: *s 内存限制: 256.0MB 本题总分:25 分

【问题描述】

小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。在冒泡排序中,每次只能交换相邻的两个元素。小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。
例如,对于字符串 lan 排序,只需要 1 次交换。对于字符串 qiao 排序,
总共需要 4 次交换。小蓝找到了很多字符串试图排序,他恰巧碰到一个字符串,需要 V 次交换,可是他忘了把这个字符串记下来,现在找不到了。
请帮助小蓝找一个只包含小写英文字母且没有字母重复出现的字符串,对该串的字符排序,正好需要 V 次交换。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。请注意字符串中可以包含相同的字符。

【输入格式】

输入的第一行包含一个整数V,小蓝的幸运数字。

【输出格式】

题面要求的一行字符串。

【样例输入】
4
1
【样例输出】
bbaa
1
【评测用例规模与约定】

漏掉了没保存上
大概是:
对于20% 的评测用例,1 ≤ n ≤ 20;
对于50% 的评测用例,1 ≤ n ≤ 100;
对于100% 的评测用例,1 ≤ n ≤ 10000;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值