AI按照我的思路复刻的代码 怎么证伪

#include <iostream>
#include <algorithm>
using namespace std;

// 静态数组大小:n≤1e5,设1e5+10避免越界(全局数组存静态区,不占栈空间)
const int MAXN = 100010;

// 糖果结构体:存储第一颗价格(x)和第二颗价格(y)
struct Candy {
    long long x, y;
} candies[MAXN]; // 静态数组存储所有糖果

long long s_x[MAXN]; // 静态数组存储S集合的x(用于反悔时加回钱)

// 排序规则:按第一颗价格(x)升序(适配sort函数)
bool cmp(const Candy& a, const Candy& b) {
    return a.x < b.x;
}

int main() {
    // 加速输入输出(考场必备优化)
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;          // 糖果种类数
    long long m;    // 总钱数(1e18范围,需long long)
    cin >> n >> m;

    // 思路1:输入糖果数据(存静态数组)
    for (int i = 0; i < n; ++i) {
        cin >> candies[i].x >> candies[i].y;
        // 每两颗总价值 = x + y(实时计算,不额外存储)
    }

    // 思路2:按第一颗价格(x)升序排序(用自定义cmp函数)
    sort(candies, candies + n, cmp);

    // 思路3:找总价值最小(w1)且第二颗价格(y)最小的糖果
    long long w1 = 1e18 + 10; // 最小两颗总价值(初始极大值)
    long long min_y = 1e18 + 10; // 对应总价值w1的最小y
    for (int i = 0; i < n; ++i) {
        long long total = candies[i].x + candies[i].y;
        if (total < w1) {
            w1 = total;
            min_y = candies[i].y;
        } else if (total == w1) {
            if (candies[i].y < min_y) {
                min_y = candies[i].y;
            }
        }
    }

    // 思路4:处理S集合(x < w1的糖果):线性遍历+实时累加(无前缀和)
    int s_cnt = 0;   // S集合的元素个数(静态数组的实际使用长度)
    long long sum_s = 0; // 实时累加S集合的总花费(替代前缀和)
    int k0 = 0;      // 初始购买S集合的糖果数量
    // 线性遍历排序后的糖果,收集x < w1且能买的糖果
    for (int i = 0; i < n; ++i) {
        // 排序后x递增,若当前x≥w1,后续均不满足,直接退出
        if (candies[i].x >= w1) {
            break;
        }
        // 先将当前糖果的x加入S集合(后续反悔可能用到)
        s_x[s_cnt++] = candies[i].x;
        // 检查是否有钱买当前糖果,有钱则更新sum和k0
        if (sum_s + candies[i].x <= m) {
            sum_s += candies[i].x;
            k0++;
        } else {
            // 钱不够,后续糖果更贵,直接退出
            break;
        }
    }
    long long rem = m - sum_s; // 初始购买后的剩余钱

    // 计算初始答案
    long long t = rem / w1;                 // 目标糖果的对数(每对2颗)
    long long rem1 = rem % w1;              // 买t对后的剩余钱
    long long max_ans = k0 + 2 * t;         // 基础数量(k0颗 + 2*t颗)
    if (rem1 >= min_y) {                    // 剩余钱够买目标糖果的第二颗
        max_ans++;
    }

    // 思路5:反悔操作:每次撤销一个S集合的糖果,重新计算答案
    while (k0 >= 1) {
        k0--; // 撤销最后一个购买的S集合糖果(k0从当前值递减)
        rem += s_x[k0]; // 加回撤销糖果的x钱(s_x[k0]是被撤销的糖果价格)

        // 重新计算当前状态的答案
        t = rem / w1;
        rem1 = rem % w1;
        long long current = k0 + 2 * t;
        if (rem1 >= min_y) {
            current++;
        }

        // 更新最大答案
        if (current > max_ans) {
            max_ans = current;
        }
    }

    // 输出最终结果
    cout << max_ans << '\n';

    return 0;
}

*洛谷被封了,正在等反省期,所以不得已来Hydro

0 comments

No comments so far...

Information

ID
40494
Time
ms
Memory
MiB
Difficulty
5
Tags
# Submissions
15
Accepted
2
Uploaded By