题解 | #D-预知#

彩虹糖的梦

https://ac.nowcoder.com/acm/contest/99458/A

一个问题,按照出题人的题解

void solve(){
    int n;
    cin>>n;
    vector<int>a(n);
    for(int i=0;i<n;i++)cin>>a[i];
    if(n==1){
        cout<<"-1\n";
        return ;
    }
    sort(a.begin(),a.end(),greater<int>());
    int m1=a[0];
    int m2=a[1];
    if(m1==1){
        cout<<0<<"\n";
        return ;
    }
    if(m2==1){
        cout<<m1-1<<"\n";
        return ;
    }
    cout<<m1<<"\n";
}

但实际上,我有一个疑问,预测最多的那一堆的牌,仍是不可行的,见下图 alt

因为我是随机的,有可能我 8 种牌,翻出了 8 张,但这 8 张,恰好是 如此以来,编号是的牌,我还剩下张! 这样,我随机翻牌,如果翻出了张中的张,怎么办?它们都是花色,重复了呀~

对于我的疑问,求解

另外给出了一个我自认为是正确的算法

void solve() {
    int n;
    cin >> n;

    vector<i64> a(n, 0);
    for (auto &x : a) cin >> x;

    if (n == 1) {
        cout << "-1\n";
        return;
    }

    sort(a.begin(), a.end());

    auto check = [&](i64 x) -> bool {
        auto b = a;
        i64 d = x / n, r = x % n;

        for (auto &y : b) y -= d;

        bool ok = true;
        for (auto y : b) {
            if (y >= 2) {
                ok = false;
                break;
            }
        }
        if (ok) return true;
        
        i64 extra = 0;
        for (auto y : b) {
            if (y >= 1) extra += (y - 1);
        }
        if (r >= extra) return true;

        return false;
    };

    i64 l = 0, r = 2e14;
    while (l < r) {
        i64 mid = (l + r) >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }

    i64 ans = l;
    cout << ans << "\n";
}

我的算法思路是,二分翻的张数,然后 check 一下这个 x 可不可行 因为是随机的,check 可行的方案,当且仅当一种花色的牌全部取完,或者是这种花色剩下一张,其他花色都是恰好只剩下一张

然后二分求解

我不知道我这种想法错在哪里,出题人回答一下,谢谢~

全部评论
如果已经知道了两张不一样的牌,我去翻这两张牌一定不会输。翻牌的最坏情况是我一直在翻的牌都是同一张。
点赞 回复 分享
发布于 2024-12-29 21:49 浙江
因为你那两次翻牌不是随机的😢,我赛时也没读对
点赞 回复 分享
发布于 2024-12-29 23:03 广东

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务