Codeforces Contest 1079 problem C Playing Piano——枚举

Little Paul wants to learn how to play piano. He already has a melody he wants to start with. For simplicity he represented this melody as a sequence a1,a2,…,an of key numbers: the more a number is, the closer it is to the right end of the piano keyboard.

Paul is very clever and knows that the essential thing is to properly assign fingers to notes he’s going to play. If he chooses an inconvenient fingering, he will then waste a lot of time trying to learn how to play the melody by these fingers and he will probably not succeed.

Let’s denote the fingers of hand by numbers from 1 to 5. We call a fingering any sequence b1,…,bn of fingers numbers. A fingering is convenient if for all 1≤i≤n−1 the following holds:

if ai<ai+1 then bi<bi+1, because otherwise Paul needs to take his hand off the keyboard to play the (i+1)-st note;
if ai>ai+1 then bi>bi+1, because of the same;
if ai=ai+1 then bi≠bi+1, because using the same finger twice in a row is dumb. Please note that there is ≠, not = between bi and bi+1.
Please provide any convenient fingering or find out that there is none.

Input
The first line contains a single integer n (1≤n≤105) denoting the number of notes.

The second line contains n integers a1,a2,…,an (1≤ai≤2⋅105) denoting the positions of notes on the keyboard.

Output
If there is no convenient fingering, print −1. Otherwise, print n numbers b1,b2,…,bn, each from 1 to 5, denoting a convenient fingering, separated by spaces.

Examples
inputCopy
5
1 1 4 2 2
outputCopy
1 4 5 4 5
inputCopy
7
1 5 7 8 10 3 1
outputCopy
1 2 3 4 5 4 3
inputCopy
19
3 3 7 9 8 8 8 8 7 7 7 7 5 3 3 3 3 8 8
outputCopy
1 3 4 5 4 5 4 5 4 5 4 5 4 3 5 4 3 5 4
Note
The third sample test is kinda “Non stop” song by Reflex.

题意:

给你一个数组,让你构造一个等长的数组,使得这个数组满足以下条件:
b数组由1到5组成,
if ai<ai+1 then bi<bi+1
if ai>ai+1 then bi>bi+1
if ai=ai+1 then bi≠bi+1

题解:

我是这样分的:如果这个数组从i有上升的趋势,那么f数组就标为1,如果有下降的趋势,那么就标为-1,比如说 1 2 3 2 1 2 3,那么f数组就是 1 0 -1 0 1 0 0 ,这样我们就可以把有变化趋势的这些标到极值,但是也可能有变数,比如说 1 2 3 4 5 5 4,这样子第二个5就不能标到极值,那么我们判断一下即可,还有第一个数也需要判断,比如说1 1 2 3 4 5 ,那么第一个数就不能标为1,而是2.
那么不可能的情况就显而易见了,连续上升或者下降的数太多。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N],f[N],ans[N];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int flag=0;
    int i=1;
    while(i<n)
    {
        if(a[i]<a[i+1])
            f[i]=1;
        while(a[i]<a[i+1])i++;
        if(a[i]>a[i+1])
            f[i]=-1;
        while(a[i]>a[i+1])i++;
        if(i>=n)
            break;
        while(a[i]==a[i+1])i++;
    }
    for(i=1;i<=n;i++)
    {
        if(a[i]==a[i-1])
        {
            if(f[i]==1)
                ans[i]=ans[i-1]==1?2:1;
            else if(f[i]==-1)
                ans[i]=ans[i-1]==5?4:5;
            else
                ans[i]=ans[i-1]==2?3:2;
        }
        else if(f[i]==1)
        {
            if(ans[i-1]==1)
            {
                flag=1;
                break;
            }
            ans[i]=1;
        }
        else if(f[i]==-1)
        {
            if(ans[i-1]==5)
            {
                flag=1;
                break;
            }
            ans[i]=5;
        }
        else if(i==1)
            ans[i]=2;
        else if(a[i]<a[i-1])
        {
            if(ans[i-1]==1)
            {
                flag=1;
                break;
            }
            ans[i]=ans[i-1]-1;
        }
        else if(a[i]>a[i-1])
        {
            if(ans[i-1]==5)
            {
                flag=1;
                break;
            }
            ans[i]=ans[i-1]+1;
        }
    }
    if(flag)
        return 0*printf("-1\n");
    for(int i=1;i<=n;i++)
        printf("%d%c",ans[i],i==n?'\n':' ');
    return 0;
}

上一篇:1079


下一篇:MyFlash快速恢复数据