正在载入在线练习界面,本页内容可直接阅读…
AK CSP › CSP-S 2025 第一轮真题 › 第41题
CSP-S 2025 第一轮 第41题:完善程序第 2 题 · 第 3 空
题目
工厂打算通过客户反馈来间接测试生产线,从而找到存在缺陷的生产线。工厂有 $n$ 条生产线(编号 $0 \sim n-1$),已知其中恰有一条生产线存在缺陷。每一轮测试为,从若干生产线的产品取样混合成一个批次发给客户。若该批次中包含缺陷生产线的产品,客户将要求退货(结果记为 1),否则正常收货(记为 0)。受售后压力限制,在所有发货批次中,最多只能有 $k$ 次退货(即结果为 1 的次数 $\leq k$)。工厂的目标是,设计最少的间接测试轮数 $w$(发货总批次),保证根据客户收货或退货的反馈结果,唯一确定存在缺陷的生产线。
以下程序实现了工厂的目标,包含两部分:i) 确定 $w$ 的最小值,并设计最优测试方案;ii) 根据测试结果推断存在缺陷的生产线。该程序确定 $w$ 最小值的方法为:由于不同的生产线故障时,测试应当返回不同的结果,因此 $w$ 轮测试的可能结果总数不应少于生产线数量。
test_subset() 函数为抽象测试接口,输入所有批次的方案并返回一个二进制编码;该编码表示为每批次的检测结果(即最低位是第 1 批次、最高位是第 $w$ 批次);其实现在此处未给出。
试补全程序。
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <vector>
using namespace std;
long long comb(int w, int i) {
if (i < 0 || i > w) {
return 0;
}
long long res = 1;
for (int t = 1; t <= i; ++t) {
res = res * (w - t + 1) / t;
}
return res;
}
// 计算长度为 w、1 的个数 ≤ k 的码字总数
long long count_patterns(int w, int k) {
long long total = 0;
for (int t = 0; t <= min(w, k); ++t) {
total += comb(w, t);
}
return total;
}
// 抽象测试接口
int test_subset(const vector<vector<int>> &plan);
int solve(int n, int k) {
// === 第 1 步:求最小 w ===
int w = 1;
while (①) {
++w;
}
cout << w << endl;
// === 第 2 步:生成测试方案 ===
vector<vector<int>> code(n, vector<int>(w, 0));
int idx = 0;
for (int ones = 0; ones <= k && idx < n; ++ones) {
vector<int> bits(w, 0);
fill(bits.begin(), bits.begin() + ones, 1);
do {
for (int b = 0; b < w; ++b) {
code[idx][b] = bits[b];
}
++idx;
if (idx >= n) {
break;
}
} while (②);
}
vector<vector<int>> plan(w);
for (int i = 0; i < w; ++i) {
for (int j = 0; j < n; ++j) {
if (③) {
plan[i].push_back(j);
}
}
}
// === 第 3 步:调用测试接口 ===
int signature = test_subset(plan);
// === 第 4 步:结果解码 ===
vector<int> sig_bits(w, 0);
for (int i = 0; i < w; ++i) {
if (④) {
sig_bits[i] = 1;
}
}
for (int j = 0; j < n; ++j) {
if (⑤) return j;
}
}
int main() {
int n, k;
cin >> n >> k;
int ans = solve(n, k);
cout << ans << endl;
return 0;
}本小题
③ 处应填( )
选项
- A. (j >> i) & 1
- B. (i >> j) & 1
- C. code[i][j] == 1
- D. code[j][i] == 1
答案
D
题解
选 D. code[j][i] == 1。
code 的定义是:
- 第一维表示生产线编号,所以
code[j]是第j条生产线的编码。 - 第二维表示测试批次,所以
code[j][i]表示第i批是否包含第j条生产线的产品。
plan[i] 存放第 i 批包含的生产线编号,因此应写:
``cpp if (code[j][i] == 1) { plan[i].push_back(j); } ``
这样,假如第 j 条生产线有缺陷,只有包含它的批次会退货,得到的反馈序列就恰好是 code[j],据此可以找到它。
A、B 使用编号的二进制位,未使用程序生成的编码;C 则把生产线和批次的下标写反了。
真题版权归 CCF 所有,本站仅用于非商业教学用途。页面加载后可直接在线作答,作答记录保存在本浏览器或账号中。 京ICP备2026056990号-1
京公网安备11010502062986号