Codeforces Round 797 (Div. 3,CF1690)全题解

Posted hans774882968

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round 797 (Div. 3,CF1690)全题解相关的知识,希望对你有一定的参考价值。

文章目录


感觉对于诸神来说这么一套水题题解没啥意义啊, 后进生的笔记罢了

传送门

作者:hans774882968以及hans774882968

本文juejin链接

A

估计最大值的下界n/3+1,直接枚举最大值就能过:

        read (n);
        int v1, v2, v3;
        rep (i, n / 3 + 1, n) 
            if ( (n - i) % 2) v1 = (n - i) / 2, v2 = v1 + 1;
            else v1 = (n - i) / 2 - 1, v2 = v1 + 2;
            if (v1 < v2 && v2 < i) 
                v3 = i;
                break;
            
        
        printf ("%d %d %d\\n", v2, v3, v1);

不过输入n = 6 7 8 9 ...可以发现最大值是可以直接写出来的式子(n - 1) / 3 + 2,所以可以进一步优化:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
#define rep(i,a,b) for(int i = (a);i <= (b);++i)
#define re_(i,a,b) for(int i = (a);i < (b);++i)
#define dwn(i,a,b) for(int i = (a);i >= (b);--i)

const int N = 2e5 + 5;

int n;

void dbg() 
    puts ("");

template<typename T, typename... R>void dbg (const T &f, const R &... r) 
    cout << f << " ";
    dbg (r...);

template<typename Type>inline void read (Type &xx) 
    Type f = 1;
    char ch;
    xx = 0;
    for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar() ) if (ch == '-') f = -1;
    for (; ch >= '0' && ch <= '9'; ch = getchar() ) xx = xx * 10 + ch - '0';
    xx *= f;

void read() 
template<typename T, typename ...R>void read (T &x, R &...r) 
    read (x);
    read (r...);


int main() 
    int T;
    read (T);
    while (T--) 
        read (n);
        int v1, v2, v3 = (n - 1) / 3 + 2;
        if ( (n - v3) % 2) v1 = (n - v3) / 2, v2 = v1 + 1;
        else v1 = (n - v3) / 2 - 1, v2 = v1 + 2;
        printf ("%d %d %d\\n", v2, v3, v1);
    
    return 0;

B

b[i]等于和不等于0讨论。

  • 对于b[i]≠0i,要求a[i]-b[i]相同,设为x
  • 对于其他i,要求max(a[i]) <= x

用set实现最方便。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
#define rep(i,a,b) for(int i = (a);i <= (b);++i)
#define re_(i,a,b) for(int i = (a);i < (b);++i)
#define dwn(i,a,b) for(int i = (a);i >= (b);--i)

const int N = 2e5 + 5;

int n, a[N], b[N];

void dbg() 
    puts ("");

template<typename T, typename... R>void dbg (const T &f, const R &... r) 
    cout << f << " ";
    dbg (r...);

template<typename Type>inline void read (Type &xx) 
    Type f = 1;
    char ch;
    xx = 0;
    for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar() ) if (ch == '-') f = -1;
    for (; ch >= '0' && ch <= '9'; ch = getchar() ) xx = xx * 10 + ch - '0';
    xx *= f;

void read() 
template<typename T, typename ...R>void read (T &x, R &...r) 
    read (x);
    read (r...);


bool jdg() 
    set<int> s1, s2;
    rep (i, 1, n) 
        if (b[i]) s1.insert (a[i] - b[i]);
        else s2.insert (a[i]);
    
    if (s1.size() > 1) return false;
    if (s1.size() == 1 && *s1.begin() < 0) return false;
    if (s1.size() == 1 && s2.size() && *s1.begin() < *s2.rbegin() ) return false;
    return true;


int main() 
    int T;
    read (T);
    while (T--) 
        read (n);
        rep (i, 1, n) read (a[i]);
        rep (i, 1, n) read (b[i]);
        puts (jdg() ? "YES" : "NO");
    
    return 0;

C

只需要求实际的开始时间,其表达式看样例就很容易写出来。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
#define rep(i,a,b) for(int i = (a);i <= (b);++i)
#define re_(i,a,b) for(int i = (a);i < (b);++i)
#define dwn(i,a,b) for(int i = (a);i >= (b);--i)

const int N = 2e5 + 5;

int n, a[N], b[N];

void dbg() 
    puts ("");

template<typename T, typename... R>void dbg (const T &f, const R &... r) 
    cout << f << " ";
    dbg (r...);

template<typename Type>inline void read (Type &xx) 
    Type f = 1;
    char ch;
    xx = 0;
    for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar() ) if (ch == '-') f = -1;
    for (; ch >= '0' && ch <= '9'; ch = getchar() ) xx = xx * 10 + ch - '0';
    xx *= f;

void read() 
template<typename T, typename ...R>void read (T &x, R &...r) 
    read (x);
    read (r...);


int main() 
    int T;
    read (T);
    while (T--) 
        read (n);
        rep (i, 1, n) read (a[i]);
        rep (i, 1, n) read (b[i]);
        rep (i, 1, n) printf ("%d%c", b[i] - max (b[i - 1], a[i]), " \\n"[i == n]);
    
    return 0;

D

直接枚举一个长为k的区间,看里面有多少个W即可。用前缀和统计W个数。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
#define rep(i,a,b) for(int i = (a);i <= (b);++i)
#define re_(i,a,b) for(int i = (a);i < (b);++i)
#define dwn(i,a,b) for(int i = (a);i >= (b);--i)

const int N = 2e5 + 5;

int n, a[N], b[N];

void dbg() 
    puts ("");

template<typename T, typename... R>void dbg (const T &f, const R &... r) 
    cout << f << " ";
    dbg (r...);

template<typename Type>inline void read (Type &xx) 
    Type f = 1;
    char ch;
    xx = 0;
    for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar() ) if (ch == '-') f = -1;
    for (; ch >= '0' && ch <= '9'; ch = getchar() ) xx = xx * 10 + ch - '0';
    xx *= f;

void read() 
template<typename T, typename ...R>void read (T &x, R &...r) 
    read (x);
    read (r...);


int main() 
    int T;
    read (T);
    while (T--) 
        read (n);
        rep (i, 1, n) read (a[i]);
        rep (i, 1, n) read (b[i]);
        rep (i, 1, n) printf ("%d%c", b[i] - max (b[i - 1], a[i]), " \\n"[i == n]);
    
    return 0;

E

对于有定值掺杂其中的式子,总是建议先尝试把定值提取出来,再进行进一步分析。——沃·兹基硕德

(a + b) / k = a / k + b / k + (a % k + b % k) / k,这就把定值a / kb / k提取出来了,后续只需要考虑a % k + b % k >= k是否成立。

这是一个很经典的贪心问题,好像是以过河为背景来着?贪心策略:先排序,再试图为当前的最小值a[i]匹配一个最小的满足条件的值。若匹配失败则丢弃a[i],成功则获得一对。用multiset来进行匹配操作即可。

有另一种做法是排序+双指针,即直接拿现有的最大值去匹配当前的最小值。这种做法也能AC,但我不清楚其正确性。

#include

以上是关于Codeforces Round 797 (Div. 3,CF1690)全题解的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #797 (Div. 3)

Codeforces Round 797 (Div. 3,CF1690)全题解

Codeforces Round 797 (Div. 3,CF1690)全题解

Codeforces Round #705 (Div. 2)

Codeforces Round #774 (Div. 2)

Codeforces Round #808 (Div. 1)(A~C)