abc374-KEYENCE Programming Contest 2024(AtCoder Beginner Contest 374)


KEYENCE Programming Contest 2024(AtCoder Beginner Contest 374)

\(solved: A B C D E\)

\(F\) 和 \(G\) 铸币 \(xkm\) 不会😭.

A – Takahashi san 2

判断给定的字符串末尾是不是 "san", 直接取 substr 判断就行.

void solve() {
    string s;
    cin >> s;
    if (s.size() >= 3 && s.substr(s.size() - 3) == "san"s) {
        cout << "Yes" << '\n';
    } else {
        cout << "No" << '\n';
    }
}

B – Unvarnished Report

给定两个字符串, 查询两个字符串第一个不一样的地方在哪, 若都相等输出 \(0\).

先判断是否相等, 然后 for 循环判断即可.

void solve() {
    string s, t;
    cin >> s >> t;
    if (s == t)
        cout << "0" << '\n';
    else {
        for (int i = 1; i < INF; i++) {
            if (i > s.size() || i > t.size()) {
                cout << i << '\n';
                return;
            }
            if (s[i - 1] != t[i - 1]) {
                cout << i << '\n';
                return;
            }
        }
    }
}

C – Separated Lunch

要求将所有部门分成两组, 让最大的组人数尽可能少.

先想到背包, 然后发现太大了根本没法做.

然后看一眼数据范围, 只有最多 \(20\) 个部门, 那直接暴力枚举 \(2^{20}\) 个状态即可.

void solve() {
    int n;
    cin >> n;
    vector<int> k(n);
    for (int i = 0; i < n; i++) cin >> k[i];
    LL sum = accumulate(k.begin(), k.end(), 0LL);
    LL ans = sum;
    for (int i = 0; i < (1 << n); i++) {
        LL a = 0;
        for (int j = 0; j < n; j++) {
            if ((i >> j) & 1) {
                a += k[j];
            }
        }
        ans = min(ans, max(a, sum - a));
    }
    cout << ans << '\n';
}

D – Laser Marking

在二维平面上打印 \(N\) 个线段. 单纯移动是每秒 \(S\) 个距离, 打印的时候是每秒 \(T\) 个距离. 对于重合的地方要求打印两次, 也就是说每次打印的结果是独立的.可以从线段的任一端点开始一直打印到另一端点, 中间不能暂停. 求起始坐标 \((0, 0)\) 的最短打印时间.

\(N \leq 6\), 那就只有 \(6! \times 2^6\) 种方式, 爆搜即可.

void solve() {
    int n;
    cin >> n;
    int t, s;
    cin >> s >> t;
    vector<array<int, 4>> lines(n);
    vector<char> vis(n);
    for (int i = 0; i < n; i++) {
        cin >> lines[i][0] >> lines[i][1] >> lines[i][2] >> lines[i][3];
    }
    double ans = INF;
    auto dfs = [&](auto self, int d, int x, int y, double time) -> void {
        if (d == n + 1) {
            ans = min(ans, time);
            return;
        }
        double pretime = time;
        for (int i = 0; i < n; i++) {
            if (!vis[i]) {
                vis[i] = 1;
                time += 1.0 / s * sqrt(pow(x - lines[i][0], 2) + pow(y - lines[i][1], 2));
                time += 1.0 / t * sqrt(pow(lines[i][0] - lines[i][2], 2) + pow(lines[i][1] - lines[i][3], 2));
                self(self, d + 1, lines[i][2], lines[i][3], time);
                time = pretime;

                time += 1.0 / s * sqrt(pow(x - lines[i][2], 2) + pow(y - lines[i][3], 2));
                time += 1.0 / t * sqrt(pow(lines[i][0] - lines[i][2], 2) + pow(lines[i][1] - lines[i][3], 2));
                self(self, d + 1, lines[i][0], lines[i][1], time);
                time = pretime;
                vis[i] = 0;
            }
        }
    };
    dfs(dfs, 1, 0, 0, 0);
    cout << fixed << setprecision(10) << ans << '\n';
}

E – Sensor Optimization Dilemma 2

生产产品, 一共要 \(N\) 个流程. 每个流程有两种机器, 机器有价格和生产效率, 可以购买任意个任意种类机器. 生产的效率为效率最低的流程. 现在给定预算, 要求最大生产效率.

最大生产效率显然可以二分, 然后考虑如何 \(check\).

背包是不行的, 因为每次预算是 \(1e7\) 级别, 那生产效率最多就是 \(1e9\).

那发现其实只有两种机器, 那一定有一种机器是不比另一种更不划算的, 最优解一定是买一些更划算的机器(或者不买), 然后差点生产效率用另一种填一下.

生产效率最大为 \(100\), 那直接暴力枚举买 \([0, 100]\) 次其中一种机器, 剩下买另一种机器的最小花费.

复杂度为 \(max(max(A_i), max(B_i)) \times nlog(max(max(A_i), max(B_i)) \times X)\).

,

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注