题解 - Japanese Student Championship 2021
前言:这场的题解由于蓝桥杯比赛拖延几天才发
关于本篇题解,目前还是有部分题没有解答出来正在加油补题ing
补题链接:Here
A - Competition
题意:给定 \(X,Y,Z\) 代表的意义为,超市一以 Y 元卖 X 克食料包
现在超市二的一包食料包重 \(Z\) 克,请问超市二的售价为多少才能比超市一便宜
思路:
理解一下题意就容易发现:\(\lfloor\frac{YZ - 1}{X}\rfloor\)
B - Xor of Sequences
给定两个严格上升的整数序列 A,B,现求仅出现在A和B的数字,最后结果升序打印
思路:
由于两个序列数据范围不大,直接暴力循环即可
然后赛后看了一下高rank的代码发现了一个函数:set_symmetric_difference
**set_symmetric_difference **可构造区间S1,S2的对称差集(出现于S1但不出现于S2的元素以及出现于S2但不出现于S1的元素);返回值为指向输出区间的尾端。
void solve() {
int n, m;
cin >> n >> m;
vector<int> A(n), B(m);
for (int &x : A) cin >> x;
for (int &x : B) cin >> x;
vector<int> C;
set_symmetric_difference(A.begin(), A.end(), B.begin(), B.end(), back_inserter(C));
for (int x : C) cout << x << " ";
}
C - Max GCD 2
题意:给定一个区间,问 \(A \le x < y \le B\) 求问最大的 \(gcd(x,y)\)
说实话,比赛的时候还真没想到这个方法。
思路:
由于数对 \((x,y)\) 的个数最多 \(2\times 10^{10}\) ,所以我们不可能计算每一对 \((x,y)\) ,相反的、并考虑是非问题“是否存在一对 \((x,y)\) 使得 \(gcd (x,y) = c\)?”
因为 \(c\) 是最大公约数,所以 \(x,y\) 都应该是 \(c\) 的倍数,相反如果在 \([A,B]\) 区间中 \(c\) 的倍数多于两个值,则可以选择 \(x,y\) 使得 \(gcd(x,y) = c\) 成立
由于 \(B \le 2\times10^5\) 所以运行速度会足够快
把上面的话转化为数学表达式:A ~ B 之间 C 的倍数 = (C 的倍数在 \(1\) ~ \(B\) 之间) - (C 的倍数在 \(1\) ~ \(A\) 之间)= \(\lfloor\frac{B}{c}\rfloor - \lfloor\frac{A - 1}{c}\rfloor\)
再转化一下就是检查 \(\lfloor\frac{A}{c}\rfloor < \lfloor\frac{B}{c}\rfloor\)
Show Code
void solve() {
int A, B;
cin >> A >> B;
for (int c = B;; c--)
if ((A + c - 1) / c < B / c) {
cout << c << endl;
return;
}
}
D - Nowhere P
给定质数 \(P\) ,求有多少序列 \((A_1,A_2,\dots,A_N)\) 满足:
显然,当 \(n = 1\) 时答案为 \(P - 1\) ,对应合法序列为 \((1),(2),\dots,(p - 1)\)
之后在这些合法序列后插入新数时,每个序列都有且仅有一个数使得这个数插入后该序列非法(该数即为 \((-\sum_ia_i)\ mod\ p\)
故答案为:\((p -1)(p-2)^{N-1}\)
跑 qpow 的时候记得取模
Show Code
const int mod = 1e9 + 7;
ll qpow(ll a, ll b) {
ll ans = 1;
a %= mod;
for (; b; b >>= 1, a = a * a % mod)
if (b & 1) ans = ans * a % mod;
return ans;
}
void solve() {
ll N, P;
cin >> N >> P;
cout << (P - 1) * qpow(P - 2, N - 1) % mod;
}
E - Level K Palindrome
本题所有的字符串均指只由小写英文字母构成的字符串
对字符串 \(s\),
- 定义其反转为: \(\operatorname{rev}(s)\), 则 \(s\) 是回文串 \(\Longleftrightarrow\) \(s = rev(s)\)
- \(+\) 运算定义为字符串的拼接
- 定义字符串上的变换为:将其中某一字符替换为一小写英文字母
定义 \(k\) 阶回文串如下:
- 空串,非回文串为 \(0\) 阶回文串
- 对 \(i\) 阶非空回文串 \(s\) 定义 \(s + rev(s)\) 为 \(i + 1\) 阶回文串
- 对 \(i\) 阶非空回文串 \(s\) 和单个字符 \(c_i\) \(s + c + rev(s)\) 为 \(i + 1\) 阶回文串
给一字符串 \(s\) 问至少经几次变换可使其恰好为 \(k\) 阶回文串
解题思路
显然,若有解则 \(k\) 不可能过大
待补
F - Max Matrix
有一个长为 \(n\) 的全零序列 \(a\) 和长为 \(m\) 的全零序列 \(b\) ,对其做如下操作
- 将 \(a\) 中的某个数赋一个值
- 将 \(b\) 中的某个数赋一个值
这两种操作一共进行 \(Q\)次,要求每次操作后都要输出
待补
G - Spanning Tree
有n个点,考虑以这n个点为顶点,满足如下条件的所有图:
- 无向图
- 给出一个矩阵 \(A\)
- 若 \(A_{i,j}=0\),则点 \(i\) 和点 \(j\) 间没有边
- 若 \(A_{i,j}=0\),则点 \(i\) 和点 \(j\) 间没有边
- 若 \(A_{i,j}=-1\),则为上述两种情况的任-种
求这些图中树的个数
思路
首先,考虑所以已经存在的边构成的图,如果有环了,则答案一定为0,否则森林中的每个树都可缩成一个点,之后用矩阵树定理即可
H - Shipping
给一个带权无向图,求满足如下条件的子图的最小边权和