跳转至

Codeforces Round 1008 (Div. 2)

又是一次掉分,最近打CF总是好难受啊。还是实力太弱太弱导致的。感觉非常的难受啊。不过也合理,我又付出了什么呢?真正自己思考的题能有几个呢?😭😭😭

真的还是很失落的,好久没上分了,甚至一直卡在青名,好久没有体会到上分的快乐了。唉唉。

比赛链接: https://codeforces.com/contest/2078

上不了分就要加训,我一定要上分。

A

正常的 A 题,直接观察发现正好平均值等于 X 的都是 YES ,然后就猜一发直接交,后面再想想吧。

void ChatGptDeepSeek()
{
    int n,x;
    cin>>n>>x;
    vector<int>a(n+1);
    for(int i=1;i<=n;i++)
        cin>>a[i];
    int sum=0;
    for(int i=1;i<=n;i++)
        sum+=a[i];
    //如果选了一个因子 那么?
    //3?
    if(sum==n*x) cout<<"YES\n";
    else cout<<"NO\n";
}

B

肯定不可能所有人都能到 \(n\) ,因为 \(a_i\ne i\) ,但是我们完全可以做到只有一个不等于 \(n\)

分下奇偶讨论一下.

\(k\) 为奇数,则我们需要第一次就能直接到 \(n\) ,所以就全等于 \(n\)

\(k\) 为偶数,则第一次不要到 \(n\) ,那就到 \(n-1\) 呗,然后 \(n-1\)\(n\)

void ChatGptDeepSeek()
{
    int n,k;
    cin>>n>>k;
    //k为奇数?
    //全为 n ,除了最后一个
    //k为偶数?
    //第一次全部去n-1 ,然后n-1去n


    //2 2?
    //2 1
    if(k&1){
        for(int i=1;i<=n-1;i++){
            cout<<n<<' ';
        }
        cout<<n-1<<'\n';
    }else{
        for(int i=1;i<n-1;i++)
            cout<<n-1<<' ';
        cout<<n<<" "<<n-1<<'\n';
    }
}

C

其实挺 easy 的 ,但是为什么一直没看出来呢。。。

太慢了,这把打得不好的很大一部分原因就是 C 写得太慢了。虽然之后还是不一定能 AC D题。

由于每个数字都不同,所以我们通过组合,肯定可以使得那个表达式是大于0或者小于0。

那么我们如果把 \(b\) 里最大的值当作 \(a_1\) ,那么肯定可以使得 \(a_2\) 后面减的是一个正数,这样 \(a_2\) 就是我们构造出的新数字,它比原数组中每一个数字都大。

构造一个比最小值小的数字也是可以做到的,但是可能会不是一个正整数。

这个思路好像还真不是很好想。

void ChatGptDeepSeek()
{
    //+b0 -b1
    int n;
    cin >> n;
    vector<int> b(n * 2 + 1);
    for (int i = 1; i <= n * 2; i++) {
        cin >> b[i];
    }
    sort(b.begin() + 1, b.end());

    // set<int> st1, st2;
    // ll s1 = 0, s2 = 0;
    // for (int i = 1; i <= n; i++)
    //     st1.insert(b[i]), s1 += b[i];
    // for (int i = n + 1; i <= n * 2; i++)
    //     st2.insert(b[i]), s2 += b[i];

    //如果说大的n 个 减去小的 n个
    //正好等于了某一个值

    //- + - + -
    //选一个很大的数字,然后减了之后正好等于an?可行吗

    //4
    //1 2 3 4
    //6-1+2-3
    ll s=b[2*n];
    //s-x=a[2n]
    for(int i=1;i<2*n;i++){
        if(i&1) s+=b[i];
        else s-=b[i];
    }
    cout<<b[2*n]<<" "<<s<<' ';
    for(int i=1;i<2*n;i++)
        cout<<b[i]<<" \n"[i+1==2*n];
}

其实能写出来 C 也是有点不容易了。。。

D

不得不说这D确实不难的,但是确实是一直没想到。。。

我单想到了哪个乘的离得近就给哪个,但是我没想到如果大小相同,可以先把多出来的留着,之后再决定怎么分配。。

好牛啊。

using ll = long long;

void ChatGptDeepSeek()
{
    int n;
    cin >> n;
    ll x = 0, L = 1, R = 1;
    while (n--) {
        char o1, o2;
        int x1, x2;
        cin >> o1 >> x1 >> o2 >> x2;
        if (o1 == 'x' && o2 == 'x') {
            if (x1 > x2) {
                L += x;
                x = L * (x1 - 1) + R * (x2 - 1);
            } else if (x1 < x2) {
                R += x;
                x = L * (x1 - 1) + R * (x2 - 1);
            } else {
                x = x * x1 + L * (x1 - 1) + R * (x2 - 1);
            }
        } else if (o1 == 'x') {
            L += x;
            x = L * (x1 - 1) + x2;
        } else if (o2 == 'x') {
            R += x;
            x = R * (x2 - 1) + x1;
        } else {
            x += x1 + x2;
        }
    }
    cout << L + R + x << '\n';
}

E

本来是一点思路都没的,看了评论区有人说用 0101010110101010 问,也有说拿 0101010101 ,我当时没太理解第一种。

我本来自己想的是,先问一次 0 ,这样就知道 \(x+y\) 的值了。第二次我想的是问一个全 \(1\) 的数字来着。这样我可以知道 \(x\)\(y\) 每一位上的 \(1\) 的数量。

但是事实上并不行,因为有的地方那一位0个1,答案会是 \(2\) 倍的这一位的值,也可能是 \(1\) 位的高一位的值。。。并不能确定具体是那一位给的贡献。

所以我们问 01010101010 就能确定奇数或者偶数位上的 1 的数量,然后用 \(x+y\) 减去这个值,就得到了 \(x\)\(y\) 的偶数位的和,就可以知道偶数位的每一位上的 \(1\) 的数量。于是就知道了每一位的情况。

其实 1010101001010101 这两个一起问,也是差不多同理的。

令奇数位上全为 \(1\)\(101010101 = n\) ,那么 \((x|n)+(y|n)-2n\) 实际上就等于 \(x+y\) 在奇数位上的和,就可以求出它们奇数位的异或的值。然后再另一个数字可以求出偶数位的异或的值,就达到了和另一种问法的相同的效果。

还是比较不容易想到的。。但感觉难度不太高的,起码只知道问什么数字就很容易写了。

constexpr int val = 715827882;

int ask(int n)
{
    cout << n << endl;
    int res;
    cin >> res;
    return res;
}
void ChatGptDeepSeek()
{
    // 问01010101非常有道理啊
    // 因为这一位的1,一定会比后面所有的和要大

    // 不对,,,但是怎么和10101010结合起来呢?
    // 直接问 0 和 0101010101吧
    //
    int sum = ask(0);
    int res = ask(val);
    vector<int> b(30);
    int x = res - sum, y = 0;
    for (int i = 29; i >= 0; i -= 2) {
        if (x >= (1 << (i + 1))) {
            // b[i] = 2;
            x -= 1 << (i + 1);
        } else if (x >= (1 << i)) {
            b[i] = 1;
            x -= 1 << i;
            y += 1 << i;
        } else {
            y += 1 << (i + 1);
            b[i] = 2;
        }
    }
    assert(x == 0);
    x = sum - y;
    for (int i = 28; i >= 0; i -= 2) {
        if (x >= (1 << (i + 1))) {
            x -= 1 << (i + 1);
            b[i] = 2;
        } else if (x >= (1 << i)) {
            x -= 1 << i;
            b[i] = 1;
        }
    }
    cout << "!" << endl;
    int m;
    cin >> m;
    for (int i = 29; i >= 0; i--) {
        // cerr << b[i] << " \n";
        if (m >> i & 1) {
            sum += (2 - b[i]) * (1 << i);
        }
    }
    cout << sum << endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    // int sum=0;
    // for(int i=29;i>=0;i--){
    //     if(i&1) sum|=1<<i;
    // }
    // cerr<<sum<<'\n';
    int T = 1;
    cin >> T;
    while (T--)
        ChatGptDeepSeek();
    return 0;
}

这里只写了第一种,另一种同理的。