完善程序(第二题):标准答案——最大化总分偏差之和

bg803054 组合题 共 个子题

(2)(标准答案)有 n 名学生参加一次考试,考试共有 m 道选择题,每道题只有 A、B 两个选项。第 i 名学生的作答用一个长度为 m 的字符串 a(i) 表示。若最终公布的标准答案与该学生在某道题上的作答相同,则该学生得 1 分,否则不得分。记第 i 名学生最终得到的总分为 r(i)。 给定每名学生的目标分数 x(i)。现在需要构造一份标准答案,使 Σ|r(i) − x(i)|(i 从 1 到 n)尽可能大。 数据满足 1 ≤ n ≤ 20,1 ≤ m ≤ 300,0 ≤ x(i) ≤ m。 以下程序从枚举符号的角度处理 Σ|r(i) − x(i)|,把它写成更易优化的形式。 对于非零整数 x,__builtin_ctzll(x) 返回 x 的二进制表示末尾连续 0 的个数。 __builtin_popcountll(x) 返回 x 的二进制表示中 1 的个数。 程序输出一组满足要求的标准答案。请补全程序。

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

int main() {
    int n, m;
    cin >> n >> m;
    vector<ll> x(n), c(n);
    for (int i = 0; i < n; i++) {
        cin >> x[i];
        c[i] = ____①____;
    }
    vector<string> a(n);
    for (int i = 0; i < n; i++)
        cin >> a[i];

    vector<int> s(n, -1);
    vector<ll> q(m, 0);
    ll C = 0, S = 0;
    for (int i = 0; i < n; i++) {
        C -= c[i];
        for (int j = 0; j < m; j++) {
            if (a[i][j] == 'A') q[j]--;
            else q[j]++;
        }
    }
    for (int j = 0; j < m; j++) S += abs(q[j]);

    ll ans = C + S;
    ull best = 0, lst = 0;

    for (ull mask = 1; mask < (1ULL << n); mask++) {
        ull g = ____②____;
        ull d = g ^ lst;
        int k = ____③____;
        C -= ____④____;
        for (int j = 0; j < m; j++) {
            ll old = q[j];
            int v = (a[k][j] == 'A' ? 1 : -1);
            q[j] -= 2ll * s[k] * v;
            S += abs(q[j]) - abs(old);
        }
        s[k] = -s[k];
        if (C + S > ans) {
            ans = C + S;
            best = g;
        }
        lst = g;
    }

    for (int i = 0; i < n; i++) {
        if (best >> i & 1) s[i] = 1;
        else s[i] = -1;
    }

    string res(m, 'A');
    for (int j = 0; j < m; j++) {
        ll v = 0;
        for (int i = 0; i < n; i++) {
            if (a[i][j] == 'A') v += s[i];
            else v -= s[i];
        }
        if (____⑤____) res[j] = 'A';
        else res[j] = 'B';
    }
    cout << res << endl;
    return 0;
}

子题 单选题

①处应填( )

A

2 * x[i] - m

B

-m + 2 * x[i] + 1

C

m - 2 * x[i]

D

m + 2 * x[i]

子题 单选题

②处应填( )

A

mask | (mask >> 1)

B

mask ^ (mask >> 1)

C

mask & (mask >> 1)

D

mask ^ ((mask >> 1) + 1)

子题 单选题

③处应填( )

A

__builtin_ctzll(d) + 1

B

__builtin_popcountll(d)

C

__builtin_ctzll(g)

D

__builtin_ctzll(d)

子题 单选题

④处应填( )

A

2ll s[k] c[k]

B

s[k] * c[k]

C

2ll * (s[k] - c[k])

D

2ll * c[k]

子题 单选题

⑤处应填( )

A

v >= (n & 1)

B

v > (n & 1)

C

v + (n & 1) >= 0

D

v * (n & 1) >= 0

正在加载题目数据…
已答 /
子题
该题型需在试卷/作业中作答,单题练习暂不支持
答案解析
讨论
发布
登录后参与讨论 立即登录
发布讨论需先绑定并验证手机号 去绑定手机号
加载中…
我
我
回复 @
回复 @
发送
还没有人讨论,来发表第一条吧