CF1768C题解

思路

这题对于每一个 aia_i,判断是否在 pp 里出现过:

  • 如果否,则 pi=aip_i=a_i,标记 aia_i 在 pp 里出现过;

qi=qiq_i=q_i,标记 aia_i;

  • 否则判断,是否在 qq 里出现过:
    ∘\circ 如果否,则 qi=aiq_i=a_i,标记 aia_i 在 pp 里出现过;
    ∘\circ 否则,说明这个 aia_i 无法放进两个数组的任何一个中,输出 NO。

接下来就是处理 p,qp,q 还没填的数了。

将填在 pp 里的数计入进 k1k_1 数组,将填在 qq 里的数计入进 k2k_2 数组,对于每个在 k1,k2k_1,k_2 其中一个里的数,记录下他们的位置。

接着,将两个数组从大到小排序,接着将每个数组剩余未填的数从大到小按照另一个数组对应的 kk 数组排序后的每一个数的位置填进去,如果这个数组当前位置的值比另一个大,输出 NO(因为这意味着 max⁡(pi,qi)≠ai\max(p_i,q_i)\not=a_i)。

如果都成功的填进去了,输出 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;
}
posted @ 2023-01-06 08:56  fengxiaoyi  阅读(25)  评论(0)    收藏  举报  来源