组合题5 个小题
已作答 0 / 5
工厂打算通过客户反馈来间接测试生产线,从而找到存在缺陷的生产线。工厂有 n 条生产线(编号 0∼n−1),已知其中恰有一条生产线存在缺陷。每一轮测试为,从若干生产线的产品取样混合成一个批次发给客户。若该批次中包含缺陷生产线的产品,客户将要求退货(结果记为 1),否则正常收货(记为 0)。受售后压力限制,在所有发货批次中,最多只能有 k 次退货(即结果为 1 的次数 ≤k)。工厂的目标是,设计最少的间接测试轮数 w(发货总批次),保证根据客户收货或退货的反馈结果,唯一确定存在缺陷的生产线。
以下程序实现了工厂的目标,包含两部分:i) 确定 w 的最小值,并设计最优测试方案;ii) 根据测试结果推断存在缺陷的生产线。该程序确定 w 最小值的方法为:由于不同的生产线故障时,测试应当返回不同的结果,因此 w 轮测试的可能结果总数不应少于生产线数量。
test_subset() 函数为抽象测试接口,输入所有批次的方案并返回一个二进制编码;该编码表示为每批次的检测结果(即最低位是第 1 批次、最高位是第 w 批次);其实现在此处未给出。
试补全程序。
1#include <algorithm>2#include <cstddef>3#include <iostream>4#include <vector>5using namespace std;6 7long long comb(int w, int i) {8 if (i < 0 || i > w) {9 return 0;10 }11 long long res = 1;12 for (int t = 1; t <= i; ++t) {13 res = res * (w - t + 1) / t;14 }15 return res;16}17 18// 计算长度为 w、1 的个数 ≤ k 的码字总数19long long count_patterns(int w, int k) {20 long long total = 0;21 for (int t = 0; t <= min(w, k); ++t) {22 total += comb(w, t);23 }24 return total;25}26 27// 抽象测试接口28int test_subset(const vector<vector<int>> &plan);29 30int solve(int n, int k) {31 // === 第 1 步:求最小 w ===32 int w = 1;33 while (__①__) {34 ++w;35 }36 cout << w << endl;37 38 // === 第 2 步:生成测试方案 ===39 vector<vector<int>> code(n, vector<int>(w, 0));40 int idx = 0;41 for (int ones = 0; ones <= k && idx < n; ++ones) {42 vector<int> bits(w, 0);43 fill(bits.begin(), bits.begin() + ones, 1);44 do {45 for (int b = 0; b < w; ++b) {46 code[idx][b] = bits[b];47 }48 ++idx;49 if (idx >= n) {50 break;51 }52 } while (__②__);53 }54 55 vector<vector<int>> plan(w);56 for (int i = 0; i < w; ++i) {57 for (int j = 0; j < n; ++j) {58 if (__③__) {59 plan[i].push_back(j);60 }61 }62 }63 64 // === 第 3 步:调用测试接口 ===65 int signature = test_subset(plan);66 67 // === 第 4 步:结果解码 ===68 vector<int> sig_bits(w, 0);69 for (int i = 0; i < w; ++i) {70 if (__④__) {71 sig_bits[i] = 1;72 }73 }74 75 for (int j = 0; j < n; ++j) {76 if (__⑤__) return j;77 }78}79 80int main() {81 int n, k;82 cin >> n >> k;83 int ans = solve(n, k);84 cout << ans << endl;85 return 0;86}④ 处应填( )