problem
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
analysis
其实这个用最最最基础的贪心就可以过了,你看这数据水的——
如果 b[i]>b[i−1] ,中位数变大就插进当前的数和最大的数
如果 b[i]<b[i−1] ,中位数变小就插进当前的数和最小的数
中位数不变就插进最大和最小的即可
用两个指针搞一搞,注意判断数出现过了没有就好了
code
#include<stdio.h>
#include<string.h>
#define MAXN 100001
using namespace std;
int a[MAXN*2],b[MAXN],f[MAXN*2];
bool bz[2*MAXN];
int n,mn,mx,tot;
int read()
{
int x=0,f=1;
char ch=getchar();
while (ch<'0' || '9'<ch)
{
if (ch=='-')f=-1;
ch=getchar();
}
while ('0'<=ch && ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
int main()
{
freopen("medians.in","r",stdin);
freopen("medians.out","w",stdout);
n=read();
for (int i=1;i<=n;i++)b[i]=read();
bz[0]=bz[2*n]=bz[b[1]]=1;
mn=1,mx=2*n-1;
f[1]=b[1],tot=1;
for (int i=2;i<=n;i++)
{
if (b[i]==b[i-1])
{
while (bz[mx])mx--;
bz[mx]=1;
f[++tot]=mx;
while (bz[mn])mn++;
bz[mn]=1;
f[++tot]=mn;
}
else if (b[i]>b[i-1])
{
while (bz[mx])mx--;
bz[mx]=1;
f[++tot]=mx;
if (!bz[b[i]])bz[b[i]]=1,f[++tot]=b[i];
else
{
while (bz[mx])mx--;
bz[mx]=1;
f[++tot]=mx;
}
}
else if (b[i]<b[i-1])
{
while (bz[mn])mn++;
bz[mn]=1;
f[++tot]=mn;
if (!bz[b[i]])bz[b[i]]=1,f[++tot]=b[i];
else
{
while (bz[mn])mn++;
bz[mn]=1;
f[++tot]=mn;
}
}
}
for (int i=1;i<=2*n-1;i++)
{
printf("%d ",f[i]);
}
return 0;
}