正在载入在线练习界面,本页内容可直接阅读…
AK CSP › CSP-J 2026 第一轮真题 › 第 39 题
CSP-J 2026 第一轮 第 39 题:平衡分割:①处应填
题目
给定一个长度为 $n$ 的字符串,其中每个字符都是一个十六进制数位。例如,字符串 016A 表示十进制下的四个数 $0, 1, 6, 10$。
现在请选择 $k$ 个($k$ 是你选定的数)切分位置 $p_{1}, p_{2}, … , p_{k}$,其中 $1 \le k < n$,且 $1 \le p_{1}< p_{2}< \cdots < p_{k}< n$。再令 $p_{0}=0$,$p_{k + 1}=n$。
对于每个 $0 \le i \le k$,计算第 $p_{i} + 1$ 个数到第 $p_{i + 1}$ 个数的平均值,记作 $b_{i}$。你的目标是使 $b_{0}, b_{1}, … , b_{k}$ 中最大值与最小值之差尽可能小,并输出这个最小值。
其中 $2 \le n \le 20$。输入字符串中的字符只可能是 0—9 或 A—F。本题假定字符采用 ASCII 编码。输出答案时保留小数点后 6 位。
以下程序通过递归枚举所有可能的连续分段方案。请补全程序。
#include <algorithm>
#include <iomanip>
#include <iostream>
using namespace std;
constexpr int N = 25;
int n, a[N];
char s[N];
double ans = 1e100;
int value(char c) { return /* ① */; }
void split(int l, int cnt, double mnb, double mxb) {
if (l > n) {
if (cnt == 0) return;
ans = min(ans, mxb - mnb);
return;
}
int sum = 0;
for (/* ② */) {
sum += a[r];
double nwb = /* ③ */;
split(/* ④ */);
}
}
int main() {
cin >> n >> s + 1;
for (int i = 1; i <= n; ++i)
a[i] = value(s[i]);
split(/* ⑤ */);
cout << fixed << setprecision(6) << ans;本小题
①处应填( )。
选项
- A. c - (c < '9' ? '0' : 'A' - 10)
- B. c - (c < 'A' ? '0' : 'A' - 10)
- C. c - (c < 'A' ? 'A' - 10 : '0')
- D. c - (c < 'A' ? '0' : 'A' + 10)
答案
B
题解
选 B。
① 的作用是把十六进制字符转换成对应的整数:
'0'~'9':用c - '0',得到 0~9。'A'~'F':用c - 'A' + 10,得到 10~15。
ASCII 编码中,数字字符都排在 'A' 前面,因此可以用 c < 'A' 区分这两种情况:
``cpp c < 'A' ? c - '0' : c - 'A' + 10 ``
把公共的 c - 提出来,就得到选项 B:
``cpp c - (c < 'A' ? '0' : 'A' - 10) ``
其他选项的问题:
- A:
c < '9'不包含'9',会把'9'错当成字母处理。 - C:数字和字母对应的转换规则写反了。
- D:字母部分算成了
c - 'A' - 10,应当是加 10。
真题版权归 CCF 所有,本站仅用于非商业教学用途。页面加载后可直接在线作答,作答记录保存在本浏览器或账号中。 京ICP备2026056990号-1
京公网安备11010502062986号