Good Bye 2019

Posted kanoon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Good Bye 2019相关的知识,希望对你有一定的参考价值。

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

A. Card Game

题意

有两个人在玩卡牌游戏,规则如下:

  • 共有 $n$ 张牌,值为 $1$ 到 $n$
  • 两个人各出一张牌,牌大者拿走两张牌
  • 手中先无牌者输掉游戏

给出一开始两个人的手牌情况(至少都有一张牌),判断第一个人能否获胜。

题解

手牌中有最大值 $n$ 者必胜。

代码

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int n, k1, k2; cin >> n >> k1 >> k2;
    bool first_win = false;
    for (int i = 0; i < n; i++) {
        int x; cin >> x;
        if (x == n and i < k1) first_win = true;
    }
    cout << (first_win ? "YES" : "NO") << "
";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

B. Interesting Subarray

题意

一个好数组定义如下:

  • 数组中的最值差大于等于数组的大小

给出一个大小为 $n$ 的数组 $a$,试找出一个好的连续子数组。

题解

最简单的情况即好数组大小为 $2$ 。

证明

若不存在大小为 $2$ 的好数组,则 $a$ 中的相邻元素最多相差 $1$,大小为 $i$ 的连续子数组最值差最多为 $i - 1$,即不存在好数组。

代码

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int n; cin >> n;
    int a[n] = {};
    for (int i = 0; i < n; i++)
        cin >> a[i];
    for (int i = 1; i < n; i++)
        if (abs(a[i] - a[i - 1]) >= 2) {
            cout << "YES" << "
"
                 << i <<   << i + 1 << "
";
            return;
        }
    cout << "NO" << "
";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

C. Make Good

题意

一个好数组定义如下:

  • $a_1 + a_2 + dots + a_n = 2cdot(a_1 oplus a_2 oplus dots       oplus a_n)$

给出一个大小为 $n$ 的非负数组 $a$,最多可向 $a$ 中添加 $3$ 个非负整数,输出一种使 $a$ 为好数组的方案。

题解

先添加 $xor = a_1 oplus a_2 oplus dots oplus a_n$ 抵消所有的异或值,之后解方程:

$sum_a + xor + x = 2x$,即 $x = sum_a + xor$ 。

代码

#include <bits/stdc++.h>
using ll = long long;
using namespace std;

void solve() {
    int n; cin >> n;
    ll sum = 0, Xor = 0;
    for (int i = 0; i < n; i++) {
        int x; cin >> x;
        sum += x, Xor ^= x;
    }
    cout << 2 << "
"
         << Xor <<   << sum + Xor << "
";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

D. Strange Device

题意

有一个大小为 $n$ 元素值两两不同的数组 $a$ 和一个检索装置,每次可以询问 $k$ 个下标,检索装置会给出其中第 $m$ 小元素的下标和值。

给出数组 $a$ 以及 $n,k$,最多询问 $n$ 次,试找出 $m$ 的值。

题解

只考虑 $a_1 sim a_{k+1}$,第 $i$ 次询问跳过下标 $i$,则检索装置会回答 $m$ 个 $a_{m+1}$,$k+1-m$ 个 $a_{m}$,又因为数组元素值两两不同,回答的两个值中较大者出现的次数即为 $m$ 。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n, k; cin >> n >> k;
    map<int, int> cnt;
    for (int i = 1; i <= k + 1; i++) {
        cout << "? ";
        for (int j = 1; j <= k + 1; j++) 
            if (j != i) cout << j <<  ;
        cout << "
";
        int pos, val; cin >> pos >> val;
        ++cnt[val];
    }
    cout << "! " << (*cnt.rbegin()).second;
}

 

以上是关于Good Bye 2019的主要内容,如果未能解决你的问题,请参考以下文章

Good Bye 2019 C. Make Good

Good Bye 2019

Good Bye 2019 C. Make Good (异或的使用)

Good Bye 2019 A. Card Game

?Good Bye 2019 B. Interesting Subarray

Good Bye 2019 A~G题解