0%

2025 bnuzh 周赛-1

(BNUZH-ACM 周赛 Round 1 - 洛谷 | 计算机科学教育新生态)

A 成绩分析

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <bits/stdc++.h>
using namespace std;

double maxn, minn, sum, x, n;

int main()
{
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> x;
sum += maxn;
maxn = max(maxn, x);
minn = min(minn, x);
}
printf("%d\n%d\n%.2lf", (int)maxn, (int)minn, sum / n);
return 0;
}

B 刷题统计

Solution

注意到 n=1018n=10^{18},一天一天减法计算会超时。考虑除法。

一周七天能做 x=5a+2bx=5a+2b 道题,那么至少要做 nx\lfloor \frac{n}{x} \rfloor 周的题。

nnxx 取余,得最后不完整的一周要做多少道题,容易计算最后一周要做几天题目。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll a, b, n, ans, week;

int main()
{
cin >> a >> b >> n;
week = 5 * a + 2 * b;
ans = n / week * 7;
n %= week;
if (a * 5 >= n)
ans += n / a + (n % a > 0);
else if (a * 5 + b >= n)
ans += 6;
else
ans += 7;
cout << ans << endl;
return 0;
}

C 整数变换

Solution-1

洛谷 AC,蓝桥杯赛场上不能满分。

对于正整数 nnnmod10n \bmod{10}nn 的最后一位。对 nn 多次对 1010 取余并除以 1010,即可算出 nn 各数位之和。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<bits/stdc++.h>
using namespace std;

int n, ans;

int main()
{
cin >> n;
while (n && ++ans) {
int num = n, sum = 0;
while (num) {
sum += num % 10;
num /= 10;
}
n -= sum;
}
cout << ans << endl;
return 0;
}

Solution-2

赛场上 AC。

注意到每一次减去的数不会超过 9×8=729\times 8=72,因此 nn 在大多数情况下都是末几位在变动。考虑预处理。

ai,ja_{i,j} 为一个数末四位为 jj,其余数位之和为 ii 时,需要操作多少次才能让第五位变动。bi,jb_{i,j} 表示一个数末四位为 jj,其余数位之和为 ii 时,使得第五位变动的第一次操作后,末四位的值。

用循环暴力计算即可预处理出 aabb 数组。

计算 nn 的答案时,计算它的 iijj,答案加上 ai,ja_{i,j},更新 n=n/10001+bi,jn=n/1000-1+b_{i,j} 即可。

相当于从几十几十地减,变成了一万一万地减。

Code

1
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
n = int(input())
a = [[0 for _ in range(105)] for _ in range(10010)]
b = [[0 for _ in range(105)] for _ in range(10010)]
ans = 0
for i in range(1, 1001):
for j in range(0, 80):
num, cnt = i, 0
while num:
res, sum = num, 0
while res:
sum += res % 10
res //= 10
num -= sum + j
cnt += 1
if num <= 0:
a[i][j] = cnt
b[i][j] = num
break
while n:
if n < 1000:
ans += a[n][0]
break
x = n % 1000
if x == 0:
res, sum = n, 0
while res:
sum += res % 10
res //= 10
n -= sum
ans += 1
continue
y = n // 1000
z = 0
while y:
z += y % 10
y //= 10
ans += a[x][z]
n = n - x + b[x][z]
print(ans)