题目大意:
定义一个符号i?j表示序列中i在j的前面。
现在有一个由1,2,.......,N,1′,2′,........,N′满足i?j?i ′?j ′。现在定义bij={j ′,if j<ij ,if j>i,然后有ai=∑Nj=1[i?bij](bij无意义)。
现在给你所有的ai,如果存在一个数列满足上述条件,那么输出“ YES ”,并且输出这个数列,否则输出“NO”。
解题思路:
我们考虑贪心构造,每次优先将当前ai=0的最小的i,并将i ′压入队列,如果不存在,那么就考虑放置队首的k ′(因为如果存在ai=0但是去放k ′,那么会有ai=?1,而且又要满足i?j?i ′?j ′)。如果都不能放置,那么就是无解。
AC代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
int N;
int a[1010]={0};
int hash[1010]={0};
int ans[2020]={0};
int dui[1010]={0};
int st=1,en=0;
int main()
{
scanf("%d",&N);
for(int i=1;i<=N;i++)
scanf("%d",&a[i]);
a[0]=2e9;
for(int p=1;p<=N*2;p++)
{
int i;
for(i=1;i<=N;i++)
if(a[i]==0 && hash[i]==0)
break;
if(i<=N)
{
ans[p]=i;
for(int j=1;j<i;j++)
if(a[j]>0)
a[j]--;
dui[++en]=i;
hash[i]=1;
}
else
{
if(st>en)
{
puts("NO");
return 0;
}
ans[p]=-dui[st];
for(int j=dui[st]+1;j<=N;j++)
if(a[j]>0)
a[j]--;
st++;
}
}
puts("YES");
for(int i=N*2;i>=1;i--)
printf("%d ",ans[i]);
return 0;
}
时间: 2024-10-19 09:10:25