2020年7月B组第一场真题
Posted 揭航
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020年7月B组第一场真题相关的知识,希望对你有一定的参考价值。
2020年7月B组第一场真题
A.跑步训练
本题总分:5 分
【问题描述】
小明要做一个跑步训练。
初始时,小明充满体力,体力值计为 10000。如果小明跑步,每分钟损耗
600 的体力。如果小明休息,每分钟增加 300 的体力。体力的损耗和增加都是
均匀变化的。
小明打算跑一分钟、休息一分钟、再跑一分钟、再休息一分钟……如此循
环。如果某个时刻小明的体力到达 0,他就停止锻炼。
请问小明在多久后停止锻炼。为了使答案为整数,请以秒为单位输出答案。
答案中只填写数,不填写单位。
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个
整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
试题 A: 跑步训练 2第十一届蓝桥杯大赛软件类省赛 C/C++ 大学 B 组
秒为单位!
10000 不是 300 的整数倍
2次算1次,减少300
32
∗
300
=
9600
32 * 300 = 9600
32∗300=9600
这是看比例的!
再来一次就体力为0了
最后一次
剩余了400
只能跑
400
/
600
∗
1
=
2
/
3
400 / 600 * 1 = 2 / 3
400/600∗1=2/3
65次是错误得!
( 64 + 2 / 3 ) ∗ 60 = 3880 (64 + 2/3) * 60 = 3880 (64+2/3)∗60=3880
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int sum = 10000;
for (int i = 1; i <= 10000; i++)
{
if(i % 2 == 1)
{
sum -= 600;
}
else
{
sum += 300;
}
if (sum <= 0)
{
cout << i;
break;
}
}
return 0;
}
B.纪念日
本题总分:5 分
【问题描述】
2020 年 7 月 1 日是中国某党成立 99 周年纪念日。
中国某党成立于 1921 年 7 月 23 日。
请问从 1921 年 7 月 23 日中午 12 时到 2020 年 7 月 1 日中午 12 时一含多少分钟?
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
一个小时60分钟
编程
52038720
/*
1. 1921年7月21日中午开始 到 2020年7月1日中午,算1天 = 60 * 24
2. 1921年7月 24 25 26 27 28 29 30 31 8天 8 * 60 * 24
3. 1921年8月 - 2020年6月
1. 1921年 8 9 10 11 12
2. 2020年 1 2 3 4 5 6
1和2 就是 366 - 31 = 335 天 335 * 60 * 24
4. 1922年 - 2019年
多少闰年?24
98 - 24 = 74
(1 + 8 + 335) + 24 * 366 + 74 * 365
*/
#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
int is_run(int year)
{
if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int count = 0;
int sum = 0;
// ll ans = ((1 + 8 + 335) + 24 * 366 + 74 * 365) * 24 * 60;
ll ans = 36138 * 24 * 60;
for (int i = 1922; i <= 2019; i++)
{
if (is_run(i))
{
count++;
}
sum++;
}
printf("%d %d\\n", count, sum);
printf("%ld", ans);
return 0;
}
计算器
得到36138天之后
36138
∗
24
∗
60
=
52038720
36138 * 24 * 60 = 52038720
36138∗24∗60=52038720
Java
import java.util.Date;
public class Main {
public static void main(String[] args) {
Date date1 = new Date(1921, 7, 23, 12, 0, 0);
Date date2 = new Date(2020, 7, 1, 12, 0, 0);
// getTime() 得到的是毫秒数
// long time = date2.getTime();
long time = date2.getTime() - date1.getTime();
System.out.println(time / 1000 / 60);
}
}
C.合并检测
思维,基本不等式
本题总分:10 分
【问题描述】
新冠疫情由新冠病毒引起,最近在 A 国蔓延,为了尽快控制疫情,A 国准
备给大量民众进病毒核酸检测。
然而,用于检测的试剂盒紧缺。
为了解决这一困难,科学家想了一个办法:合并检测。即将从多个人(k
个)采集的标本放到同一个试剂盒中进行检测。如果结果为阴性,则说明这 k
个人都是阴性,用一个试剂盒完成了 k 个人的检测。如果结果为阳性,则说明
至少有一个人为阳性,需要将这 k 个人的样本全部重新独立检测(从理论上看,
如果检测前 k - 1 个人都是阴性可以推断出第 k 个人是阳性,但是在实际操作中
不会利用此推断,而是将 k 个人独立检测),加上最开始的合并检测,一共使用
了 k + 1 个试剂盒完成了 k 个人的检测。
A 国估计被测的民众的感染率大概是 1%,呈均匀分布。请问 k 取多少能
最节省试剂盒?
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个
整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
答案:10
分析1
假设A国有n个人,感染者有n/100
每k个人一组,共n/k组,共用n/k瓶试剂
按照最坏的情况,每多出一个感染者就多用k瓶试剂,
因此共用n/k+(n/100) * k瓶试剂
n是定值,所以求(1/k+k/100)最小
由于
a
+
b
>
=
2
a
b
a+b>=2\\sqrt{ab}
a+b>=2ab
当且仅当a = b时,取等号
即1/k=k/100时,取得最小值
解得k = 10
分析2
总人数n,感染率为p,每次k人,总次数sum
// 能整除就不用 + 1把
sum = ([n / k ]) + ([n / k])(k * p *(k + 1))
// 不能整除
sum = ([n / k]) + ([n / k])(k * p * (k + 1))
化简为
sum = (n / k)(1 + 0.01k*(k + 1))
求导使得sum最小,k = 10
D.REPEAT 程序
本题总分:15 分
【问题描述】
附件 prog.txt 中是一个用某种语言写的程序。
其中 REPEAT k 表示一个次数为 k 的循环。循环控制的范围由缩进表达,
从次行开始连续的缩进比该行多的(前面的空白更长的)为循环包含的内容。
例如如下片段:
REPEAT 2:
A = A + 4
REPEAT 5:
REPEAT 6:
A = A + 5
A = A + 7
A = A + 8
A = A + 9
A = A + 4 所在的行到 A = A + 8 所在的行都在第一行的
循环两次中。
REPEAT 6: 所在的行到 A = A + 7 所在的行都在 REPEAT 5: 循环中。
A = A + 5 实际总共的循环次数是 2 × 5 × 6 = 60 次。
请问该程序执行完毕之后,A 的值是多少?
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个
整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
使用Python即可,Python根据缩进才算循环的
- REPEAT替换为
-
:
替换为):
-
最后输出
print(A)
答案:241830
比如这样三个i 循环也是可以的
A = 0
for i in range(0, 2):
A = A + 4
for i in range(0, 5):
for i in range(0, 6):
A = A + 5
A = A + 7
A = A + 8
A = A + 9
print(A)
不附录代码了,懂意思就行
E.矩阵
动态规划
本题总分:15 分
【问题描述】
把 1 ∼ 2020 放在 2 × 1010 的矩阵里。要求同一行中右边的比左边大,列中下边的比上边的大。一共有多少种方案?
答案很大,你只需要给出方案数除以 2020 的余数即可。
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
1340
#include <iostream>
#include <cstdio>
using namespace std;
const int MAX_N = 2025;
int dp[MAX_N][MAX_N];
int n = 2020;
const int MOD = 2020;
int main()
{
dp[1][1] = 1;
for (int i = 2; i <= n; ++i)
{
for (int j = 1; j <= i; ++j)
{
dp[i][j] += dp[i - 1][j - 1];
if (i - j <= j)
{
dp[i][j] += dp[i - 1][j];
}
dp[i][j] %= MOD;
}
}
// for (int i = 1; i <= n; ++i)
// {
// for (int j = 1; j <= n; ++j)
// {
// printf("%5d", dp[i][j]);
// }
// cout << "\\n";
// }
cout << dp[n][n / 2];
return 0;
}
F.整除序列
时间限制: 1.0s 内存限制: 256.0MB 本题总分:15
【问题描述】
有一个序列,序列的第一个数是 n,后面的每个数是前一个数整除 2,出这个序列中值为正数的项。
【输入格式】
输入一行包含一个整数 n。
【输出格式】
输出一行,包含多个整数,相邻的整数之间用一个空格分隔,表示答案。
【样例输入】
【样例输入】
20
【样例输出】
20 10 5 2
【评测用例规模与约定】
对于 80% 的评测用例,1 ≤ n ≤ 10^9。
对于所有评测用例,1 ≤ n ≤ 10^18。
- 输入最大
1000000000000000000
1000000000000000000 500000000000000000 250000000000000000 125000000000000000 62500000000000000 31250000000000000 15625000000000000 7812500000000000 3906250000000000 1953125000000000 976562500000000 488281250000000 244140625000000 122070312500000 61035156250000 30517578125000 15258789062500 7629394531250 3814697265625 1907348632812 953674316406 476837158203 238418579101 119209289550 59604644775 29802322387 14901161193 7450580596 3725290298 1862645149 931322574 465661287 232830643 116415321 58207660 29103830 14551915 7275957 3637978 1818989 909494 454747 227373 113686 56843 28421 14210 7105 3552 1776 888 444 222 111 55 27 13 6 3 1
- 一半就用
n >> 1;
#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
int main()
{
ios :: sync_with_stdio(false);
ll n;
cin >> n;
while(n > 0)
{
cout << n << " ";
n = n >> 1;
}
return 0;
}
G.解码
时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分
【问题描述】
小明有一串很长的英文字母,可能包含大写和小写。
在这串字母中,有很多连续的是重复的。小明想了一个办法将这串字达得更短:将连续的几个相同字母写成字母 + 出现次数的形式。
例如,连续的 5 个 a,即 aaaaa,小明可以简写成 a5(也可能简写aa3a 等)。对于这个例子:HHHellllloo,小明可以简写成 H3el5o2。为了方达,小明不会将连续的超过 9 个相同的字符写成简写的形式。
现在给出简写后的字符串,请帮助小明还原成原来的串。
【输入格式】
输入一行包含一个字符串。
【输出格式】
输出一个字符串,表示还原后的串。
【样例输入】
H3el5o2
【样例输出】
HHHellllloo
【评测用例规模与约定】
对于所有评测用例,字符串由大小写英文字母和数字组成,长度不100。
请注意原来的串长度可能超过 100。
- 思路1
- 设置一个收字母的数组
- 一个对应的字母个数的数组
- 然后再输出
- 思路2
- 遇到字母先输出
- 遇到数字输出前面的字母n - 1次
思路1
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
const int MAX_N = 5000;
int cnt_idx;
int ch_idx;
char ch[MAX_N];
int cnt[MAX_N];
int main()
{
string str;
cin >> str;
for (int i = 0; i < str.length(); ++i)
{
if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z'))
{
ch[ch_idx++] = str[i];
if(!(str[i + 1] >= '0' && str[i + 1] <= '9'))
{
cnt[cnt_idx++] = 1;
}
}
else if (str[i] >= '0' && str[i] <= '9')
{
cnt[cnt_idx++] = str[i] - '0';
}
}
// for (int i = 0; i < ch_idx; i++)
// {
// cout << ch[i] << " ";
// }
// cout << "\\n";
// for (int i = 0; i < cnt_idx; ++i)
// {
// cout << cnt[i] << " ";
// }
for (int i = 0; i < ch_idx; ++i)
{
for (int j = 0; j < cnt[i]; j++)
{
printf("%c", ch[i]);
}
}
return 0;
}
思路2
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
int cnt;
int main()
{
string str;
cin >> str;
for (int i = 0; i < str.length(); ++i)
{
if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z'))
{
cout << str[i];
}
else
{
cnt = str[i] - '0' - 1;
// 比如3,就输出2次
while(cnt-- && cnt >= 0)
{
cout << str[i - 1];
}
}
}
return 0;
}
H.走方格
这不是算法之美的机器人走方格吗? 算法之美里面的
问题描述
时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分
【问题描述】
在平面上有一些二维的点阵。
这些点的编号就像二维数组的编号一样,从上到下依次为第 1 至第 n 行,从左到右依次为第 1 至第 m 列,每一个点可以用行号和列号来表示。
现在有个人站在第 1 行第 1 列,要走到第 n 行第 m 列。只能向右或者向下走。
注意,如果行号和列数都是偶数,不能走入这一格中。
问有多少种方案。
【输入格式】
输入一行包含两个整数 n, m。
【输出格式】
输出一个整数,表示答案。
【样例输入】
3 4
【样例输出】
2
【样例输入】
6 6
【样例输出】
0
【评测用例规模与约定】
对于所有评测用例,1 ≤ n ≤ 30, 1 ≤ m ≤ 30。
注意行号和列数都是偶数就不能走
#include <iostream>
#include <cstdio>
using namespace std;
const int MAX_N = 40;
int n, m;
int dp[MAX_N][MAX_N];
// 行号和列数都是偶数就不能走
int ans = 0;
int main()
{
cin >> n >> m;
dp[1][1] = 1;
for (int i = 2; i <= m; ++i)
{
dp[1][i] = 1;
}
for (int i = 2; i <= n; ++i)
{
dp[i][1] = 1;
}
for (int i = 2; i <= n; ++i)
{
for (int j = 2; j <= m; ++j)
{
// 行号和列数都是偶数就不能走
if (i % 2 == 0 && j % 2 == 0)
{
continue;
}
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
cout << dp[n][m];
return 0;
}
I.整数拼接
时间限制: 1.0s 内存限制: 256.0MB 本题总分:25 分
【问题描述】
给定义个长度为 n 的数组 A1,A2,⋅⋅⋅,An。你可以从中选出两个数 Ai 和 Aj ( i 不等于 j ),然后将 Ai 和 Aj 一前一后拼成一个新的整数。例如 12 和 345 可以拼成 12345 或 34512。注意交换 Ai 和 Aj 的顺序总是被视为 2 种拼法,即便是 Ai=Aj 时。
请你计算有多少种拼法满足拼出的整数是 K 的倍数。
【输入格式】
第一行包含 2 个整数 n 和 K。
第二行包含 n 个整数 A1,A2,⋅⋅⋅,An。
【输出格式】
一个整数代表答案。
【评测用例规模与约定】
对于 30% 的评测用例,1≤n≤1000,1≤K≤20,1≤Ai≤10^4。
对于所有评测用例,1≤n≤10^5,1≤K≤10^5,1≤Ai≤10^9。
【样例输入】
4 2
1 2 3 4
【样例输出】
6
看错题目了。。。明明抽2个数拼接在一起
- 暴力求解
- 选出2个数,一前一后,2个整体的数拼接在一起,然后遍历即可
暴力
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
// typedef long long ll;
#define ll long long
const int MAX_N 以上是关于2020年7月B组第一场真题的主要内容,如果未能解决你的问题,请参考以下文章