Good Bye 2019

Posted lanly

tags:

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

A. Card Game (CF 1270 A)

题目大意

两个人各持有(k_1)(k_2)张牌,牌序号唯一且在范围(1)~(n)其中(n=k_1+k_2)。一次操作两个各亮出一张牌,谁牌序号大,谁拿对方的牌,最后没牌者输,问先手是否必赢。

解题思路

很显然谁持有最大牌谁赢......

但是(tourist)能在一分钟内读完题并敲好代码提交过了真是太强了。


神奇的代码

#include <bits/stdc++.h>
#define MIN(a,b) ((((a)<(b)?(a):(b))))
#define MAX(a,b) ((((a)>(b)?(a):(b))))
#define ABS(a) ((((a)>0?(a):-(a))))
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<PII> VPII;
typedef vector<LL> VL;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;

template <typename T>
void read(T &x) {
    int s = 0, c = getchar();
    x = 0;
    while (isspace(c)) c = getchar();
    if (c == 45) s = 1, c = getchar();
    while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    if (s) x = -x;
}

template <typename T>
void write(T x, char c = ' ') {
    int b[40], l = 0;
    if (x < 0) putchar(45), x = -x;
    while (x > 0) b[l++] = x % 10, x /= 10;
    if (!l) putchar(48);
    while (l) putchar(b[--l] | 48);
    putchar(c);
}

int n,k1,k2;

int main(void) {
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int kase; read(kase);
    for (int i = 1; i <= kase; i++) {
        //printf("Case #%d: ", i);
        read(n);
        read(k1);
        read(k2);
        bool qwq=false;
        for(int u,i=1;i<=k1;++i){
            read(u);
            if (u==n) qwq=true;
        }
        for(int u,i=1;i<=k2;++i){
            read(u);
        }
        if (qwq) printf("YES
");
        else printf("NO
");
    }
    return 0;
}



B. Interesting Subarray (CF 1270 B)

题目大意

给定一个长度为(n)的数组(a),问是否存在某个区间([l,r]),有(max-mingeq k),其中(max=maxlimits_{i in [l,r]}(a_i))(min=minlimits_{i in [l,r]}(a_i))(k=r-l+1),存在则输出(YES)并输出任意一个符合要求的区间,否则输出(NO).

解题思路

我们考虑一个符合题目条件的区间([l,r]),其中最大值和最小值在端点处是最优的选择,不失一般性,我们设最大值在(r)处,最小值在(l)处,则(max-min=(max_1-max_2)+(max_2-max_3)+...+(max_{k-1}-max_k)=geq k),从中我们可以看出至少有一个(max_i-max_{i+1}>1),才能有该不等式成立,那也一定有至少一个位置(i)(abs(a_i-a_{i+1})geq 2)才行。


神奇的代码

#include <bits/stdc++.h>
#define MIN(a,b) ((((a)<(b)?(a):(b))))
#define MAX(a,b) ((((a)>(b)?(a):(b))))
#define ABS(a) ((((a)>0?(a):-(a))))
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<PII> VPII;
typedef vector<LL> VL;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;

template <typename T>
void read(T &x) {
    int s = 0, c = getchar();
    x = 0;
    while (isspace(c)) c = getchar();
    if (c == 45) s = 1, c = getchar();
    while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    if (s) x = -x;
}

template <typename T>
void write(T x, char c = ' ') {
    int b[40], l = 0;
    if (x < 0) putchar(45), x = -x;
    while (x > 0) b[l++] = x % 10, x /= 10;
    if (!l) putchar(48);
    while (l) putchar(b[--l] | 48);
    putchar(c);
}

int n,u,v;

int main(void) {
    //ios::sync_with_stdio(false);
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int kase; read(kase);
    for (int i = 1; i <= kase; i++) {
        //printf("Case #%d: ", i);
        read(n);
        read(u);
        bool qwq=false;
        int l=0;
        for(int i=2;i<=n;++i){
            read(v);
            if (ABS(v-u)>1) {qwq=true;l=i-1;}
            u=v;
        }
        if (qwq) printf("YES
%d %d
",l,l+1);
        else printf("NO
");
    }
    return 0;
}



C. Make Good (CF 1270 C)

题目大意

给定(n)个正整数,设(n)个数的和为(sum),异或为(x),若(sum=2x)则这个序列是(good)的,如果不是(good),最多可增加三个正整数,使得这个序列变成(good),求添加数的个数以及数的大小。

解题思路

首先(sum)一定要是偶数,否则我们先加一个数(1),然后再考虑(sum)(x)大小。

注意到异或两次同一个数相当于不变,那么如果(sum<2x),那么我们只要再增加两个同样的数(qwq=dfrac{2x-sum}{2}),这样(x)不变,而(sum)也变成了(2x)

如果(sum>2x),我们再一开始增加一个超大超大的数,让(sum<2x)即可,由于(sumleq 10^{15}),那我们就增加一个(10^{16})的数,即(2^{50}),如果(sum)是奇数,就加(2^{50}+1),然后根据上面的情况即可。

对应代码为注释部分。

这题还有另一种加法,即加两个数(x)(sum+x),这样和就变成(2(sum+x)),异或值变成(sum+x),这样也符合题意。


神奇的代码

#include <bits/stdc++.h>
#define MIN(a,b) ((((a)<(b)?(a):(b))))
#define MAX(a,b) ((((a)>(b)?(a):(b))))
#define ABS(a) ((((a)>0?(a):-(a))))
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<PII> VPII;
typedef vector<LL> VL;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;

template <typename T>
void read(T &x) {
    int s = 0, c = getchar();
    x = 0;
    while (isspace(c)) c = getchar();
    if (c == 45) s = 1, c = getchar();
    while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    if (s) x = -x;
}

template <typename T>
void write(T x, char c = ' ') {
    int b[40], l = 0;
    if (x < 0) putchar(45), x = -x;
    while (x > 0) b[l++] = x % 10, x /= 10;
    if (!l) putchar(48);
    while (l) putchar(b[--l] | 48);
    putchar(c);
}

int main(void) {
    //ios::sync_with_stdio(false);
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int kase; read(kase);
    for (int i = 1; i <= kase; i++) {
        //printf("Case #%d: ", i);
        int n;
        LL sum,xx,u,a;
        read(n);
        sum=xx=0;
        for(int i=1;i<=n;++i){
            read(u);
            sum+=u;
            xx=xx^u;
        }
        printf("2
%lld %lld
",xx,xx+sum);
        /* if ((xx<<1ll)==sum) printf("0

");
        else{
            a=(1ll<<50ll);
            if (sum&1ll) a=a|1ll;
            sum+=a;
            xx=(xx^a);
            xx<<=1;
            LL qwq=xx-sum;
            printf("3
%lld %lld %lld
",a,(qwq>>1),(qwq>>1));
        } */
    }
    return 0;
}



D. Strange Device (CF 1270 D)

题目大意

交互题。

给定(n)(k),以及一个你并不知道长度为(n)的数俩俩不同的数列和(m),每次你可以问(k)个互不相同的下标,对方会告诉你这些下标对应的值里,从小到大排列第(m)个小数的位置和值。不能问多于(n)次。最后你的程序要猜出(m)值。

解题思路

一开始妄图想找到(k)个数然后问它们一波得到(m)值结果不可行。然后妄图用并查集维护每个数在(m)的左边还是右边发现数太多了不可控(qwq)所以我们要考虑少点的数,比如就前(k+1)个数,每次我们选这其中的(k)个数,相当于把其中的一个数从(k+1)个数中剔除,然后我们考虑这个剔除的数对第(m)个数的影响。

假设在这(k+1)个数中,第(m)个数的值为(a),则如果剔除的一个数(i)小于等于(a),则第(m)个数会变成另一个数(b),如果大于(a),则第(m)个数还是(a)。纵观我们剔除(k+1)次的结果,可以知道数(a)会出现(k+1-m次),而数(b)会出现(m)次,于是我们统计较大的数出现的次数就是答案(m)


神奇的代码

#include <bits/stdc++.h>
#define MIN(a,b) ((((a)<(b)?(a):(b))))
#define MAX(a,b) ((((a)>(b)?(a):(b))))
#define ABS(a) ((((a)>0?(a):-(a))))
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<PII> VPII;
typedef vector<LL> VL;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;

template <typename T>
void read(T &x) {
    int s = 0, c = getchar();
    x = 0;
    while (isspace(c)) c = getchar();
    if (c == 45) s = 1, c = getchar();
    while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    if (s) x = -x;
}

template <typename T>
void write(T x, char c = ' ') {
    int b[40], l = 0;
    if (x < 0) putchar(45), x = -x;
    while (x > 0) b[l++] = x % 10, x /= 10;
    if (!l) putchar(48);
    while (l) putchar(b[--l] | 48);
    putchar(c);
}

int main(void) {
    //ios::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n,k;
    read(n);
    read(k);
    vector<bool> sign(k+2,false);
    int ma=0,cnt=0;
    for(int i=1;i<=k+1;++i){
        sign[i]=true;
        sign[i-1]=false;
        printf("? ");
        for(int j=1;j<=k+1;++j) if (!sign[j]) printf("%d ",j);
        puts("");
        fflush(stdout);
        int u,v;
        read(u);read(v);
        if (ma<v){cnt=1;ma=v;}else if (ma==v) ++cnt;
    }
    printf("! %d
",cnt);
    fflush(stdout);
    return 0;
}



May 2020 will be the year of high ratings for the hard workers.





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