2022年蓝桥杯省赛C/C++大学A组代码
2023的题还需要烧烤一下/(ㄒoㄒ)/~~
所以先做2022的题
暂未完成:最长上升子序列
P8770 [蓝桥杯 2022 省 A] 填空问题
题目描述
试题 A :裁纸刀
【问题描述】
小蓝有一个裁纸刃,每次可以将一张纸沿一条直线裁成两半。
小蓝用一张纸打印出两行三列共
在上面的例子中,小蓝的打印机没办法打印到边缘,所以边缘至少要裁
如果小蓝要用一张纸打印出
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
试题 B:灭鼠先锋
【问题描述】
灭鼠先锋是一个老少咸宜的棋盘小游戏,由两人参与,轮流操作。
灭鼠先锋的棋盘有各种规格,本题中游戏在两行四列的棋盘上进行。游戏的规则为:两人轮流操作,每次可选择在棋盘的一个空位上放置一个棋子,或在同一行的连续两个空位上各放置一个棋子,放下棋子后使棋盘放满的一方输掉游戏。
小蓝和小乔一起玩游戏,小蓝先手,小乔后手。小蓝可以放置棋子的方法很多,通过旋转和翻转可以对应如下四种情况:
1 | X000 XX00 OXOO OXXO |
其中 O
表示棋盘上的一个方格为空,X
表示该方格已经放置了棋子。
请问,对于以上四种情况,如果小蓝和小乔都是按照对自己最优的策略来玩游戏,小蓝是否能获胜。如果获胜,请用 V
表示,否则用 L
表示。请将四种情况的胜负结果按顺序连接在一起提交。
解法
裁纸刀
灭鼠先锋
博弈论
1 |
|
[蓝桥杯 2022 省 A] 求和
题目描述
给定
输入格式
输入的第一行包含一个整数
第二行包含
输出格式
输出一个整数
样例 #1
样例输入 #1
1 | 4 |
样例输出 #1
1 | 117 |
提示
对于
对于所有评测用例,
蓝桥杯 2022 省赛 A 组 C 题。
解法
后缀和1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using ll=unsigned long long;
const int N=(2e5)+5;
using namespace std;
int n;
int a[N];
ll sum=0;
ll ans=0;
int main() {
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=n-1;i>=0;i--){
ans+=a[i]*sum;
sum+=a[i];
}
printf("%lld",ans);
return 0;
}
[蓝桥杯 2022 省 A] 选数异或
题目描述
给定一个长度为
输入格式
输入的第一行包含三个整数
第二行包含
接下来
输出格式
对于每个询问, 如果该区间内存在两个数的异或为 yes
, 否则输出 no
。
样例 #1
样例输入 #1
1 | 4 4 1 |
样例输出 #1
1 | yes |
提示
【样例说明】
显然整个数列中只有 2,3 的异或为 1 。
【评测用例规模与约定】
对于
对于
对于所有评测用例,
蓝桥杯 2022 省赛 A 组 D 题。
解法
异或:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const int N=(1e5)+5;
using namespace std;
int n,m,x;
unordered_map<int,int> mp;//数值,对应位置
int f[N];//对于查询[l,r],f[r]表示[l,r]要有相配答案,l的最右
int main() {
scanf("%d%d%d",&n,&m,&x);
int a;
for(int i=1;i<=n;i++){
scanf("%d",&a);
f[i]=max(f[i-1],mp[a^x]);//找到达到要求的最左边界
mp[a]=i;
}
int l,r;
while(m--){
scanf("%d%d",&l,&r);
if(l<=f[r])
printf("yes\n");
else
printf("no\n");
}
return 0;
}
[蓝桥杯 2022 省 A] 爬树的甲壳虫
题目描述
有一只甲壳虫想要爬上一颗高度为
输入格式
输入第一行包含一个整数
接下来
输出格式
输出一行包含一个整数表示答案,答案是一个有理数,请输出答案对质数
样例 #1
样例输入 #1
1 | 1 |
样例输出 #1
1 | 2 |
样例 #2
样例输入 #2
1 | 3 |
样例输出 #2
1 | 623902744 |
提示
对于
对于
对于所有评测用例,
蓝桥杯 2022 省赛 A 组 E 题。
bgm🐌🎵
是🐞不是🐌喂
解法
状态转移
设从高度
即
转移方程:
求
费马小定理的一种表述:对于任意整数
和质数 ,有
模运算和逆元
在模运算中,使用逆元将除法转换为乘法,避免了直接计算分数。
快速幂模板
乘法逆元模板
逆元的定义:如果存在一个整数
,使得 ,那么 就是 在模 下的逆元 费马小定理的一种表述:如果
是一个质数,且 与 互质,那么:
另一种表述:对于任意整数和质数 ,有
计算
对于模数
快速幂函数
函数quick_pow
用于计算
通过不断将指数
将分数转换为模运算下的乘法。
总代码
1 |
|
时间复杂度
每次计算逆元的时间复杂度为
总时间复杂度为
[蓝桥杯 2022 省 A] 青蛙过河
题目描述
小青蛙住在一条河边,它想到河对岸的学校去学习。小青蛙打算经过河里的石头跳到对岸。
河里的石头排成了一条直线,小青蛙每次跳跃必须落在一块石头或者岸上。不过,每块石头有一个高度,每次小青蛙从一块石头起跳,这块石头的高度就会下降
小青蛙一共需要去学校上
请问小青蛙的跳跃能力至少是多少才能用这些石头上完
输入格式
输入的第一行包含两个整数
第二行包含
输出格式
输出一行, 包含一个整数, 表示小青蛙需要的最低跳跃能力。
样例 #1
样例输入 #1
1 | 5 1 |
样例输出 #1
1 | 4 |
提示
【样例解释】
由于只有两块高度为
【评测用例规模与约定】
对于
对于
对于所有评测用例,
蓝桥杯 2022 省赛 A 组 F 题。
bgm🐸🎵
解法
贪心+前缀和
对于每个起点
如果某个区间的石头总高度不足,则增加
1 |
|
[蓝桥杯 2022 省 A] 最长不下降子序列
题目描述
给定一个长度为
最长不下降子序列是指序列中的一个子序列,子序列中的每个数不小于在它之前的数。
输入格式
输入第一行包含两个整数
第二行包含
输出格式
输出一行包含一个整数表示答案。
样例 #1
样例输入 #1
1 | 5 1 |
样例输出 #1
1 | 4 |
提示
对于
对于
对于
对于所有评测用例,
蓝桥杯 2022 省赛 A 组 G 题。
解法
1 | ``` |
5 2
0 1 1
0 3 2
4 3 5
6 8 1
-51 -33 21
2
3
### 样例输出 #1
1 1 3 4 -11
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
## 提示
对于 $30 \%$ 的评测用例,$1 \leq n \leq 500$ ;
对于 $60 \%$ 的评测用例,$1 \leq n \leq 5000$;
对于所有评测用例,$1 \leq n \leq 2\times10^5,-10^{9} \leq x_{i}, y_{i} \leq 10^{9}, 1 \leq L, z_{i} \leq 10^{9}$ 。
样蓝桥杯 2022 省赛 A 组 H 题。
## 题解
为什么不试试优先队列呢?
此处建议用斜率代替角度,角度每个网站的数据要求精度不一样。但我过了洛谷和蓝桥杯官网就懒得改了```(*ꈍ◡ꈍ*)```
```cpp
#include <bits/stdc++.h>
using ll = long long;
using ull = unsigned long long;
const int N = (2e5) + 5;
const double pi2 = 2 * M_PI; // 2*圆周率pi
using namespace std;
struct point {
int id; // 序号
int z; // 碰到增加的值
ull r; // 半径的平方
double angle; // 角度(以从y轴正方向开始的顺时针角度表示)
bool operator>(const point &other) const {
return angle > other.angle; // 优先队列按角度排序
}
} p[N];
int main() {
int n;//棒的个数
ull l;//棒的长度
__int128 l2;//棒的长度的平方,棒的长度的平方。__int128防止超过数据范围
scanf("%d%lld", &n, &l);
l2 = l * l;
ll x, y;
for (int i = 0; i < n; i++) {
scanf("%lld%lld%d", &x, &y, &p[i].z);
p[i].id = i;
p[i].r = x * x + y * y;//半径的平方
p[i].angle = atan2(x, y);//算角度。atan2可以处理为0的情况,注意是顺时针从y轴正方向开始
if (p[i].angle < 0)//把第二、三象限的角度转过来
p[i].angle = pi2 + p[i].angle;
}
sort(p, p + n, [](const point &a, const point &b) -> bool {
return a.r < b.r;
});//按半径排序
priority_queue<point, vector<point>, greater<>> q; // 按角度排序的优先队列
int pos;
for (pos = 0; pos < n && p[pos].r <= l2; pos++) {
q.push(p[pos]);
}
int cnt = 1, last_cnt = 1;//排名,并列排名
int ans[N];//答案
double rounds = pi2, angle = 0; // rounds 表示本轮结束的角度,angle 保存上一个被扫到的点的角度
memset(ans, -1, sizeof(ans));//初始化为-1
const double eps = 1e-11; // 浮点数比较阈值。1e-9官网过不了
while (!q.empty()) {
point u = q.top();
q.pop();
if (u.angle > rounds + eps) // 如果当前点的角度超过本轮结束的角度
rounds += pi2;
if (fabs(u.angle - angle) < eps) { // 判断两角度是否“相等”,用并列排名
ans[u.id] = last_cnt;
} else {
last_cnt=ans[u.id]=cnt;//更新并列的排名
angle=u.angle;//角度
}
++cnt;//更新排名
l += u.z;
l2 = l * l;
while (pos < n && p[pos].r <= l2) {
// 新点的角度转换到绝对角度,先加上当前轮次的偏移量
p[pos].angle += (rounds - pi2);
if (p[pos].angle < angle - eps) {
p[pos].angle += pi2;
}
q.push(p[pos]);
++pos;
}
}
printf("%d", ans[0]);
for (int i = 1; i < n; i++)
printf(" %d", ans[i]);
return 0;
}
[蓝桥杯 2022 省 A] 数的拆分
题目描述
给定
输入格式
输入第一行包含一个整数
接下来
输出格式
对于每次询问,如果 yes
,否则输出 no
。
样例 #1
样例输入 #1
1 | 7 |
样例输出 #1
1 | no |
提示
【样例说明】
第
【评测用例规模与约定】
对于
对于
对于
对于所有评测用例,
蓝桥杯 2022 省赛 A 组 I 题。
解法
1 |
|
[蓝桥杯 2022 省 A] 推导部分和
题目描述
对于一个长度为
然而,小蓝并不知道数列中每个数的值是多少,他只知道它的
输入格式
第一行包含 3 个整数
接下来
接下来
输出格式
对于每个询问, 输出一行包含一个整数表示答案。如果答案无法确定, 输出 UNKNOWN
。
样例 #1
样例输入 #1
1 | 5 3 3 |
样例输出 #1
1 | 15 |
提示
对于
对于
对于
对于
对于
对于所有评测用例,
蓝桥杯 2022 省赛 A 组 J 题。
解法
1 |
|