首页 > 其他分享 >CF1032C Playing Piano

CF1032C Playing Piano

时间:2023-01-07 02:55:06浏览次数:57  
标签:ch int CF1032C else lst ans Piano now Playing

CF1032C Playing Piano - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目大意是:能否构造一个长度为 \(n\) 的值域为 \([1, 5]\) 的整数序列,使得相邻两个数之间的大小关系满足给定的大小关系。

给定的大小关系可能是大于,小于和不等于。

CF 官方给的 dp 做法是假的。实际上只需要一个橙色难度的简单构造。题解区唯一的一篇构造写的不够清楚而且代码比较难懂(还是 Go 语言的),这里我贡献一篇。

把序列拆分为连续大于段,连续小于段和连续不等段。

贪心地,连续大于段从 \(5\) 开始,填 \((5, 4, 3, 2, 1)\)。连续小于段从 \(1\) 开始,填 \((1, 2, 3, 4, 5)\)。填不下去了就是连续长度大于 \(5\) 了,报个无解。

连续不等段直接在 \(2, 3\) 之间振荡。\(3, 4\) 之间,\(2, 4\) 之间也可以,但不要涉及到 \(1, 5\),看后面就知道原因了。

然后考虑一下段和段的边界。

先小于后大于 \(a < b < c > d > e\)。发现 \(c\) 明显应该填 \(5\),也就是跟随后面那个段,因为要让后面尽可能连续下去。按照上面的贪心填法对应的构造方案是 \((1, 2, 5, 4, 3)\)。

先大于后小于同理,跟后面。

先不等后小于 \(a \ne b \ne c < d < e\)。会发现 \(c\) 应该填 \(1\) 最好,也是跟随后面。这里就是为什么不等段的振荡最好不涉及 \(1\) 和 \(5\),否则可能影响边界。

先不等后大于同理,跟后面。

先小于后不等 \(a < b < c \ne d \ne e\),这个 \(c\) 可以跟前面。

先大于后不等同理,跟前面。

但是这样会有一个问题:\(\cdots > a > b > c \ne d < e < f < \cdots\)。\(d\) 应该怎么填?如果 \(c\) 没填 \(1\) 自然老办法 \(d\) 填 \(1\),如果 \(c\) 填了 \(1\) 呢?

不难发现,此时 \(d\) 只能填 \(2\)。因为根据我们的贪心想法,\(c\) 此时都为 \(1\) 了就说明前面必有一段 \(5 > 4 > 3 >2 >1\) 的链,将 \(c\) 修改为 \(2\) 前面就会不合法。大小于号翻过来后情况也是类似的。

注意 \(n = 1\) 可能需要特判,根据你咋写的。

复杂度 \(\Theta(n)\)。

/*
 * @Author: crab-in-the-northeast 
 * @Date: 2023-01-07 01:36:54 
 * @Last Modified by: crab-in-the-northeast
 * @Last Modified time: 2023-01-07 02:23:00
 */
#include <bits/stdc++.h>
inline int read() {
    int x = 0;
    bool f = true;
    char ch = getchar();
    for (; !isdigit(ch); ch = getchar())
        if (ch == '-')
            f = false;
    for (; isdigit(ch); ch = getchar())
        x = (x << 1) + (x << 3) + ch - '0';
    return f ? x : (~(x - 1));
}

const int maxn = (int)1e5 + 5;

int a[maxn];
char b[maxn]; // b[i] 表示 b[i] 和 b[i + 1] 的大小关系

int main() {
    int n = read();
    if (n == 1) {
        puts("1");
        return 0;
    }
    
    for (int i = 1; i <= n; ++i)
        a[i] = read();
    for (int i = 1; i < n; ++i) {
        if (a[i] < a[i + 1])
            b[i] = '<';
        else if (a[i] > a[i + 1])
            b[i] = '>';
        else
            b[i] = '!';
    }
    
    int lst = 1;
    if (b[1] == '>')
        lst = 5;
    else if (b[1] == '!')
        lst = 2;
    
    std :: vector <int> ans = {lst};
    
    for (int i = 2; i < n; ++i) {
        int now;
        char p = b[i - 1], q = b[i];
        if (p == '<') {
            if (lst == 5)
                break;
            now = lst + 1;
            if (q == '>')
                now = 5;
        } else if (p == '>') {
            if (lst == 1)
                break;
            now = lst - 1;
            if (q == '<')
                now = 1;
        } else if (p == '!') {
            if (q == '!') {
                now = 3;
                if (lst == 3)
                    now = 2;
            } else if (q == '<') {
                now = 1;
                if (lst == 1)
                    now = 2;
            } else if (q == '>') {
                now = 5;
                if (lst == 5)
                    now = 4;
            }
        }

        ans.push_back(lst = now);
    }

    if (b[n - 1] == '<')
        ans.push_back(5);
    else if (b[n - 1] == '>')
        ans.push_back(1);
    else
        ans.push_back(lst == 5 ? 4 : 5);
    
    if ((int)ans.size() == n)
        for (int x : ans)
            printf("%d ", x);
    else
        printf("-1");
    puts("");
    return 0;
}

标签:ch,int,CF1032C,else,lst,ans,Piano,now,Playing
From: https://www.cnblogs.com/crab-in-the-northeast/p/cf1032c.html

相关文章

  • Blondie24 Playing at the Edge of AI
    Blondie24|ScienceDirectBlondie24tellsthestoryofacomputerthattaughtitselftoplaycheckers[西洋跳棋程序]farbetterthanitscreatorsevercouldby......
  • About Piano
    Theday beforeyesterday,IsawtheThanksgivingDay'sshowinAmerica.BeforeChristmas,IwanttoplayJing Bellonthepiano. Ididsomeworklike"h......
  • Patch Available for Cut or Copy displaying “insuf
    you'reexperiencingfrequent“insufficientmemory”errorswhendoingsmallcutorcopyoperationsinVisualStudio2010RTM,please​​downloadthispatch​......
  • B. Playing with GCD
    传送门题意:一个长度为n的数组a,\(a_i=gcd(b_i,b_{i+1})\),问是否存在这样的b数组能够构成a思路:总结:gcd可以推导出lcm的规律,图片中的那个>=关系是代表......