zoukankan      html  css  js  c++  java
  • CodeForces 1252E Songwriter(贪心)

    题目:

    Andi is a mathematician, a computer scientist, and a songwriter. After spending so much time writing songs, he finally writes a catchy melody that he thought as his best creation. However, the singer who will sing the song/melody has a unique vocal range, thus, an adjustment may be needed.

    A melody is defined as a sequence of NN notes which are represented by integers. Let AA be the original melody written by Andi. Andi needs to adjust AA into a new melody BB such that for every ii where 1i<N1≤i<N:

    • If Ai<Ai+1Ai<Ai+1, then Bi<Bi+1Bi<Bi+1.
    • If Ai=Ai+1Ai=Ai+1, then Bi=Bi+1Bi=Bi+1.
    • If Ai>Ai+1Ai>Ai+1, then Bi>Bi+1Bi>Bi+1.
    • |BiBi+1|K|Bi−Bi+1|≤K, i.e. the difference between two successive notes is no larger than KK.

    Moreover, the singer also requires that all notes are within her vocal range, i.e. LBiRL≤Bi≤R for all 1iN1≤i≤N.

    Help Andi to determine whether such BB exists, and find the lexicographically smallest BB if it exists. A melody XX is lexicographically smaller than melody YY if and only if there exists jj (1jN1≤j≤N) such that Xi=YiXi=Yi for all i<ji<j and Xj<YjXj<Yj.

    For example, consider a melody A={1,3,5,6,7,8,9,10,3,7,8,9,10,11,12,12}A={1,3,5,6,7,8,9,10,3,7,8,9,10,11,12,12} as shown in the following figure. The diagonal arrow up in the figure implies that Ai<Ai+1Ai<Ai+1, the straight right arrow implies that Ai=Ai+1Ai=Ai+1, and the diagonal arrow down implies that Ai>Ai+1Ai>Ai+1.

    Supposed we want to make a new melody with L=1L=1, R=8R=8, and K=6K=6. The new melody B={1,2,3,4,5,6,7,8,2,3,4,5,6,7,8,8}B={1,2,3,4,5,6,7,8,2,3,4,5,6,7,8,8} as shown in the figure satisfies all the requirements, and it is the lexicographically smallest possible.

    Input

    Input begins with a line containing four integers: NLRKK (1N1000001≤N≤100000; 1LR1091≤L≤R≤109; 1K1091≤K≤109) representing the number of notes in the melody, the vocal range (LL and RR), and the maximum difference between two successive notes in the new melody, respectively. The next line contains NN integers: AiAi (1Ai1091≤Ai≤109) representing the original melody.

    Output

    Output in a line NN integers (each separated by a single space) representing the lexicographically smallest melody satisfying all the requirements, or output -1 if there is no melody satisfying all the requirements. Note that it might be possible that the lexicographically smallest melody which satisfies all the requirements to be the same as the original melody.

    Examples

    Input
    16 1 8 6
    1 3 5 6 7 8 9 10 3 7 8 9 10 11 12 12
    
    Output
    1 2 3 4 5 6 7 8 2 3 4 5 6 7 8 8
    
    Input
    16 1 8 6
    1 3 5 6 7 8 9 10 3 7 8 9 10 11 12 13
    
    Output
    -1
    
    Input
    16 1 10 10
    1 3 5 6 7 8 9 10 3 7 8 9 1 11 12 13
    
    Output
    1 2 3 4 5 6 7 8 1 2 3 4 1 2 3 4
    

    Note

    Explanation for the sample input/output #1

    This is the example from the problem description.

    题意:

      给出长度为n的序列a,要求构造长度为n的序列b且字典序最小,要求相邻的两数之间,b[i]和b[i+1]的大小关系与a[i]和a[i+1]的大小关系相同,并且相邻的abs(b[i]-b[i+1])<=k,同时任意b[i]要在[l,r]的范围内。

    思路:

      因为要求字典序最小,所以我们可以先预处理出每个位置能取的数字范围,然后贪心地从左往右取。

      预处理数字范围的时候从后往前,分3种情况:

      1.a[i] == a[i+1]

        这种时候显然l[i]=l[i+1],r[i]=r[i+1]

      2.a[i] > a[i+1]

        因为梯度最大是k,故r[i] = max(r[i+1]+k,R),在后一个最大可能的基础上再加上k,同时保证范围不越界

        l[i] = l[i+1] + 1,最小的情况只能是最小可能数+1,这时候应判一下越界问题

      3.a[i] < a[i+1]

        同2,l[i] = max(L,l[i+1] - k),最小情况是最小可能数-k,同时保证范围不越界

           r[i] = r[i+1] - 1,最大情况是最大可能数-1,判越界问题

    代码:

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn = 1e5 + 7;
    int l[maxn],r[maxn],a[maxn],L,R,n,k;
    int main() {
        scanf("%d%d%d%d",&n,&L,&R,&k);
        for (int i=1; i<=n; ++i) {
            scanf("%d",&a[i]);
        }
        int f = 1;
        l[n] = L; r[n] = R;
        for (int i=n-1; i>=1; --i) {
            if(a[i] == a[i+1]) {
                l[i] = l[i+1];
                r[i] = r[i+1];
            }
            else if(a[i] > a[i+1]) {
                l[i] = l[i+1] + 1;
                r[i] = min(r[i+1] + k,R);
            }
            else {
                l[i] = max(L,l[i+1] - k);
                r[i] = r[i+1] - 1;
            }    
            if(l[i] > r[i] || l[i] > R || r[i] < L) f = 0;
        }
        if(f == 0) {
            printf("-1");
            return 0;
        }
        int ans = l[1];
        for (int i=1; i<=n; ++i) {
            printf("%d ",ans);
            if(a[i] == a[i+1]) continue;
            else if(a[i] > a[i+1]) {
                ans = max(ans-k,l[i+1]);
            }
            else ans = max(ans+1,l[i+1]);
        }
        
        return 0;
    }
  • 相关阅读:
    【百度地图API】让用户选择起点和终点的驾车导航
    JS解决通过按钮切换图片的问题
    JavaScript (JS)基础:DOM 浅析 (含数组Array、字符串String基本方法解析)
    JavaScript (JS)基础:ECMAScript 浅析 (含Math基本方法解析)
    感谢Sylvia的技术支持
    0904 存储过程、触发器、事务、视图、生成脚本
    0903 连接查询
    0901 子查询
    0831 模糊查询,排序查询,聚合函数,时间日期函数,数学函数,字符串函数
    0829 数据库的增删改查
  • 原文地址:https://www.cnblogs.com/Remilia-Scarlet/p/14520432.html
Copyright © 2011-2022 走看看