蓝桥杯 2022年国赛真题
C/C++ 大学C组
试题 A: 斐波那契与 7
本题总分: 5 5 5 分
【问题描述】
斐波那契数列的递推公式为 : : : F n = F n − 1 + F n − 2 F_n = F_{n−1} + F_{n−2} Fn=Fn−1+Fn−2,其中 F 1 = F 2 = 1 F_1 = F_2 = 1 F1=F2=1。
请问,斐波那契数列的第 1 1 1 至 202202011200 202202011200 202202011200 项(含)中,有多少项的个位是 7 7 7。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个由大写字母组成的字符串,在提交答案时只填写这个字符串,填写多余的内容将无法得分。
26960268160
找循环节
找到斐波那契数列在个位上的循环节,然后将答案拆分成三部分就完事了。
#include <stdio.h>
const long long n = 202202011200;
int map[10][10], sum[101];
int main() {
int i = 1, x = 0, y = 1, z = 1;
for (; !map[x][y]; ++i) {
map[x][y] = 1;
sum[i] = sum[i - 1] + (y == 7);
x = y, y = z, z = (x + y) % 10;
}
printf("%lld",
(n - map[x][y] + 1) / (i - map[x][y]) * (sum[i - 1] - sum[map[x][y] - 1])
+ sum[(n - map[x][y] + 1) % (i - map[x][y]) + map[x][y] - 1]
);
}
试题 B: 小蓝做实验
本题总分: 5 5 5 分
【问题描述】
小蓝很喜欢科研,他最近做了一个实验得到了一批实验数据,一共是两百万个正整数。如果按照预期,所有的实验数据 x x x 都应该满足 1 0 7 ≤ x ≤ 1 0 8 10^7 ≤ x ≤ 10^8 107≤x≤108。但是做实验都会有一些误差,会导致出现一些预期外的数据,这种误差数据 y y y 的范围是 1 0 3 ≤ y ≤ 1 0 12 10^3 ≤ y ≤ 10^{12} 103≤y≤1012 。由于小蓝做实验很可靠,所以他所有的实验数据中 99.99 % 99.99\% 99.99% 以上都是符合预期的。小蓝的所有实验数据都在 p r i m e s . t x t \mathrm{primes.txt} primes.txt 中,现 在他想统计这两百万个正整数中有多少个是质数,你能告诉他吗?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
342693
欧拉筛
首先排除 M i l l e r \mathrm{Miller} Miller- R o b i n \mathrm{Robin} Robin,一般 T T T 次询问的题目, T T T 越大,对单次询问响应的复杂度要求越高,于是考虑欧拉筛线性筛出不大于 1 e 8 1e8 1e8 的质数, O ( 1 ) O(1) O(1) 响应 99.99 % 99.99\% 99.99% 的询问,而剩下询问中, y y y 不会大于 1 e 16 1e16 1e16,利用因数的对称性,可以在 O ( y ) O(\sqrt y) O(y) 的复杂下响应。
#include <stdio.h>
const int N = 100000000;
int n, ans, p[5761456];
bool pb[N + 1];
int main() {
for (int i = 2; i <= N; ++i) {
if (!pb[i]) p[n++] = i;
for (int j = 0; j < n; ++j) {
if (i * p[j] > N) break;
pb[i * p[j]] = 1;
if (i % p[j] == 0) break;
}
}
freopen("primes.txt", "r", stdin);
for (long long i, n; ~scanf("%lld", &n);) {
if (n > N) {
for (i = 0; p[i] <= 1000000; ++i)
if (n % p[i] == 0) break;
if (p[i] > 1000000) ++ans;
} else if (!pb[n]) ++ans;
}
printf("%d", ans);
}
试题 C: 取模
时间限制: 1.0 s 1.0\mathrm s 1.0s 内存限制: 256.0 M B 256.0\mathrm{MB} 256.0MB 本题总分: 10 10 10 分
【问题描述】
给定 n , m n,m n,m,问是否存在两个不同的数 x , y x,y x,y 使得 1 ≤ x < y ≤ m 1 ≤ x < y≤m 1≤x<y≤m 且 n mod x = n mod y n \operatorname{mod} x = n \operatorname{mod} y nmodx=nmody。
【输入格式】
输入包含多组独立的询问。
第一行包含一个整数 T T T 表示询问的组数。
接下来 T T T 行每行包含两个整数 n , m n,m n,m,用一个空格分隔,表示一组询问。
【输出格式】
输出 T T T 行,每行依次对应一组询问的结果。如果存在,输出单词 Y e s \mathrm{Yes} Yes;如果不存在,输出单词 N o \mathrm{No} No。
【样例输入】
3
1 2
5 2
999 99
【样例输出】
No
No
Yes
【评测用例规模与约定】
对于 20 % 20\% 20% 的评测用例, T ≤ 100 , n , m ≤ 1000 T ≤100 ,n,m≤1000 T≤100,n,m≤1000;
对于 50 % 50\% 50% 的评测用例, T ≤ 10000 , n , m ≤ 1 0 5 T ≤10000 ,n,m≤10^5 T≤10000,n,m≤105;
对于所有评测用例, 1 ≤ T ≤ 1 0 5 , 1 ≤ n ≤ 1 0 9 , 2 ≤ m ≤ 1 0 9 1≤T ≤10^5 ,1≤n≤10^9 ,2≤m≤10^9 1≤T≤105,1≤n≤109,2≤m≤109。
中国剩余定理
依题意,对给定两个整数 n , m n,m n,m, n ≥ 1 , m ≥ 2 n \geq 1,m \geq 2 n≥1,m≥2,判断其逆命题 k = 1 , 2 , ⋯ , m k = 1, 2, \cdots,m k=1,2,⋯,m, n mod k n \operatorname{mod} k nmodk 恰取遍 [ 0 , m − 1 ] [0, m-1] [0,m−1] 是否成立,
近一步引出等价逆命题, n mod k ≡ k − 1 n \operatorname{mod} k \equiv k-1 nmodk≡k−1 是否在 k ∈ [ 1 , m ) k \in [1,m) k∈[1,m) 下都成立,因为 n mod 1 ≡ 0 n \operatorname{mod} 1 \equiv 0 nmod1≡0, n mod 2 n \operatorname{mod} 2 nmod2 若想使上述命题为真,只能取 1 1 1,以此类推。
于是有同余方程组,当 n n n 满足下列方程组时,无论如何也找不到两个不同的数 x , y x,y x,y 使得 1 ≤ x < y ≤ m 1 ≤ x < y≤m 1≤x<y≤m 且 n mod x = n mod y n \operatorname{mod} x = n \operatorname{mod} y nmodx=nmody。 { n ≡ 1 ( m o d 2 ) n ≡ 2 ( m o d 3 ) ⋮ ⋮ n ≡ m − 1 ( m o d m ) \begin{cases} n \equiv 1 & \pmod 2 \\ n \equiv 2 & \pmod 3 \\ \quad\ \vdots & \qquad \vdots\\ n \equiv m-1 & \pmod m \end{cases} ⎩ ⎨ ⎧n≡1n≡2 ⋮n≡m−1(mod2)(mod3)⋮(modm) 自顶向下合并同余方程 2 p − 3 q = 2 − 1 2p -3q = 2 - 1 2p−3q=2−1,解得 p = 2 , q = 1 p = 2, q = 1 p=2,q=1,代入 { n ≡ 2 p + 1 ( m o d 2 ) n ≡ 3 q + 2 ( m o d 3 ) \begin{cases} n \equiv 2p+1 & \pmod 2 \\ n \equiv 3q+2 & \pmod 3 \\ \end{cases} { n≡2p+1n≡3q+2(mod2)(mod3) 可得 n ≡ 5 ( m o d lcm ( 2 , 3 ) = 6 ) n \equiv 5 \pmod {\operatorname{lcm}(2, 3) = 6} n≡5(modlcm(2,3)=6),假设 n = lcm { k , 1 ≤ k ≤ m } − 1 n = \operatorname{lcm}\{k, 1\leq k \leq m\} - 1 n=lcm{ k,1≤k≤m}−1,当 m ≤ 3 m \leq 3 m≤3 时显然成立,考虑 m + 1 m + 1 m+1,联立同余方程: { n ≡ lcm { k , 1 ≤ k ≤ m } − 1 ( m o d lcm { k , 1 ≤ k ≤ m } ) n ≡ m ( m o d m + 1 ) \begin{cases} n \equiv \operatorname{lcm}\{k, 1\leq k \leq m\} - 1 & \pmod {\operatorname{lcm}\{k, 1\leq k \leq m\}} \\ n \equiv m & \pmod {m+1} \end{cases} { n≡lcm{ k,1≤k≤m}−1n≡m(modlcm{ k,1≤k≤m})(modm+1) 解: lcm { k , 1 ≤ k ≤ m } p − ( m + 1 ) q = m − lcm { k , 1 ≤ k ≤ m } + 1 \operatorname{lcm}\{k, 1\leq k \leq m\}p-(m+1)q = m -\operatorname{lcm}\{k, 1\leq k \leq m\}+1 lcm{ k,1≤k≤m}p−(m+1)q=m−lcm{ k,1≤k≤m}+1,得: p = − 1 , q = − 1 p=-1,q=-1 p=−1,q=−1,联立可得 n ≡ − 1 ( m o d lcm { k , 1 ≤ k ≤ m + 1 } ) n\equiv-1 \pmod {\operatorname{lcm}\{k, 1\leq k \leq m+1\}} n≡−1(modlcm{ k,1≤k≤m+1}),即模 lcm { k , 1 ≤ k ≤ m + 1 } \operatorname{lcm}\{k, 1\leq k \leq m+1\} lcm{ k,1≤k≤m+1} 的加法逆元 lcm { k , 1 ≤ k ≤ m + 1 } − 1 \operatorname{lcm}\{k, 1\leq k \leq m+1\}-1 lcm{ k,1≤k≤m+1}−1。
这启发了我们,只需枚举不超过 22 22 22 个数( lcm { k , 1 ≤ k ≤ 23 } ≥ 1 e 9 \operatorname{lcm}\{k, 1\leq k \leq 23\} \geq 1e9 lcm{ k,1≤k≤23}≥1e9),就可以判断 n , m n,m n,m 是否满足上列同余式,继而判断 n , m n,m n,m 是否满足原命题。
#include <stdio.h>
int _, n, m;
int main() {
for (scanf("%d", &_); _--;) {
scanf("%d %d", &n, &m);
int flag = 0;
if (m > 22) m = 22;
for (int i = 2; i <= m; ++i)
if (n % i != i - 1) flag = 1;
puts(flag ? "Yes" : "No");
}
}
试题 D: 内存空间
时间限制: 1.0 s 1.0\mathrm s 1.0s 内存限制: 256.0 M B 256.0\mathrm{MB} 256.0MB 本题总分: 10 10 10 分
【问题描述】
小蓝最近总喜欢计算自己的代码中定义的变量占用了多少内存空间。
为了简化问题,变量的类型只有以下三种:
i n t : \mathrm{int}: int:整型变量,一个 i n t \mathrm{int} int 型变量占用 4 B y t e 4\ \mathrm{Byte} 4 Byte 的内存空间。
l o n g : \mathrm{long}: long:长整型变量,一个 l o n g \mathrm{long} long 型变量占用 8 B y t e 8\ \mathrm{Byte} 8 Byte 的内存空间。
S