CF1768C题解
思路
这题对于每一个 ,判断是否在 里出现过:
- 如果否,则 ,标记 在 里出现过;
,标记 ;
- 否则判断,是否在 里出现过:
如果否,则 ,标记 在 里出现过;
否则,说明这个 无法放进两个数组的任何一个中,输出NO。
接下来就是处理 还没填的数了。
将填在 里的数计入进 数组,将填在 里的数计入进 数组,对于每个在 其中一个里的数,记录下他们的位置。
接着,将两个数组从大到小排序,接着将每个数组剩余未填的数从大到小按照另一个数组对应的 数组排序后的每一个数的位置填进去,如果这个数组当前位置的值比另一个大,输出 NO(因为这意味着 )。
如果都成功的填进去了,输出 YES,然后输出这两个数组。
代码
#include<bits/stdc++.h>
using namespace std;
int t,n,a[200010],p[200010],q[200010];
bool m1[200010],m2[200010];
struct QAQ{
int sum,id;
}k1[200010],k2[200010];
bool cmp(QAQ _a,QAQ _b){
return _a.sum<_b.sum;
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(m1,0,sizeof(m1));
memset(m2,0,sizeof(m2));
int n1=0,n2=0,now1=1,now2=1;
bool f=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(!m1[a[i]]) p[i]=a[i],k1[++n1].sum=a[i],k1[n1].id=i,m1[a[i]]=1;
else if(!m2[a[i]]) q[i]=a[i],k2[++n2].sum=a[i],k2[n2].id=i,m2[a[i]]=1;
else if(!f){
printf("NO\n");
f=1;
}
}
if(f) continue;
sort(k1+1,k1+n1+1,cmp);
sort(k2+1,k2+n2+1,cmp);
for(int i=1;i<=n1;i++){
while(m2[now2]) now2++;
if(now2<=0||now2>k1[i].sum){
printf("NO\n");
goto qaq;
}
q[k1[i].id]=now2;
m2[now2]=1;
now2++;
}
for(int i=1;i<=n2;i++){
while(m1[now1]) now1++;
if(now1<=0||now1>k2[i].sum){
printf("NO\n");
goto qaq;
}
p[k2[i].id]=now1;
m1[now1]=1;
now1++;
}
printf("YES\n");
for(int i=1;i<=n;i++)
printf("%d ",p[i]);
putchar('\n');
for(int i=1;i<=n;i++)
printf("%d ",q[i]);
putchar('\n');
qaq:;
}
return 0;
}

浙公网安备 33010602011771号