[贪心]JZOJ P3619——medians

Description

让我们定义A 为1, 2, 3,。。。, 2 * N - 1 的一个全排列。

定义数列B 为A 的前缀的中位数形成的数列:B[i] 为A[1],A[2],。。。,A[2 * i - 1] 的中位数。

注:对于M 个数的中位数(M 是奇数),可以通过排序后取中间的数得到。

给出N 和数列B。找到一个全排列A 使得前缀中位数形成的数列恰好为B。

Input

输入包含两行。

第一行包含一个整数N。

第二行描述B:N 个整数,用空格隔开。

Output

输出A:含2 * N - 1 个空格隔开的整数的一行。如果有多个全排列A 能够形成输入的数列B,

那么你可以输出任意一个。测试数据中保证总是存在解。

Sample Input

5

1 3 3 4 5

Sample Output

1 9 3 2 4 8 7 5 6

Data Constraint

• 1 <= A[i] <= 2 * N - 1,对于任意i 从1 到2 * N - 1

• 1 <= B[i] <= 2 * N - 1,对于任意i 从1 到N

• 1 <= N <= 100 000

• 60% 的数据有N <= 1000

题解

贪心大法
易得,b[1]就是全排列的第一个数
这题要分类讨论
    一:f[b[i]]==fase(也就之前出现过该中位数或被选过)
            ①b[i]==b[i-1] 之前将维护的最大和最小的数输出
            ②b[i]<b[i-1] 输出维护的最大的两个数
            ③b[i]>b[i-1] 输出维护的最小的两个数
    二:f[b[i]]==true(之前没有输出过)先将这个数输出
            ①a[i]<a[i-1] 输出维护最小的数
            ②a[i]>a[i-1] 输出维护最大的数

代码

#include<cstdio>
#include<memory.h>
#include<iostream>
using namespace std;
int n,m,l,r,a[100010],p,s,b; 
bool f[100010];
int main()
{
    //freopen("medians.in","r",stdin);
    //freopen("medians.out","w",stdout);
    scanf("%d",&n);
    m=n*2-1;
    l=1; r=m;
    memset(f,true,sizeof(f));
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if (i==1) 
        {
            f[a[i]]=false;
            printf("%d ",a[i]);
            if (a[i]==l) l++;
        }
        else 
        if (f[a[i]]==false)
        {
            if (a[i]>a[i-1])
            {
                while (f[r]==false) r--;
                printf("%d ",r);
                f[r]=false;
                r--;
                while (f[r]==false) r--;
                printf("%d ",r);
                f[r]=false;
                r--;
            }
            else 
            if (a[i]<a[i-1])
            {
                while (f[l]==false) l++;
                printf("%d ",l);
                f[l]=false;
                l++;
                while (f[l]==false) l++;
                printf("%d ",l);
                f[l]=false;
                l++;
            }
            else
            {
                while (f[l]==false) l++;
                printf("%d ",l);
                f[l]=false;
                l++;
                while (f[r]==false) r--;
                printf("%d ",r);
                f[r]=false;
                r--;
            }
        }
        else 
        {
            p=i*2-1;
            f[a[i]]=false;
            printf("%d ",a[i]); 
            if (a[i]==r) r--; 
            if (a[i]<a[i-1])
            {
                while (f[l]==false) l++;
                printf("%d ",l);
                f[l]=false;
                l++;
            }
            else
            {
                while (f[r]==false) r--;
                printf("%d ",r);
                f[r]=false;
                r--;
            }
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章