CF1227B题解

CF1227B题解

题意

给一个数组 q,其中:

  • q1=p1
  • q2=max(p1,p2)
  • q3=max(p1,p2,p3)
  • qn=max(p1,p2,p3,pn)

求符合要求的 p 数组。

思路

有以下两点:

  1. 无解的情况:q[i]<i,为啥呢?答:那是因为 q 数组的第 i 个是为 p 的前 i 个数中最大的。又因为 p1n 中不重复的数字组成的数组。所以要是 q[i]<i,就是无解。
  2. 求解操作呢,我借鉴了 SunArrebol 这位大佬,但是他没有解释,首先先讲解法:
bool ok=0;//记录是否有符合题意的p数组 
		for(int i=1; i<=n; i++) p[i]=i;
		for(int i=1; i<=n; i++){
			scanf("%d",&q[i]);
			if(q[i]<i) ok=1;//标记为无解。
			else swap(p[i],p[q[i]]);//交换 
		}

那为啥是上面那样呢?首先一开始已经赋值 p1,2,3,n,此时录入 q,无解就不说了,我们要理解的是交换这一步,为啥是这样交换呢?分析如下:

我们都知道,q 数组的第 i 个是为 p 的前 i 个数中最大的,那么输入一个 q[i] 分为以下两种情况:

{q[i]=p[i]=max(p[1],p[2],p[3],p[i])p[i]max(p[1],p[2],p[3],p[i]),q[i]=q[i1]

对于第一种情况,p[i] 是没有被交换过的,所以 q[i]=p[i]=i,所以交换了等于没交换。

对于第二种情况,因为 q[i]=q[i1],所以就说明前面 p[q[i]] 已经交换过原来的小的了,在 p[q[i]]<p[i]<q[i],所以也不影响 q 数组最大值,操作合理。

总结

  1. 在做操作的时候记得赋初值。
  2. 记得特判无解的情况。
  3. 别忘了换行!

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath> 
using namespace std;
int p[100005],q[100005],T,n;
int main(){
	scanf("%d",&T);
	while(T--){//有T组数据 
		scanf("%d",&n);
		bool ok=0;//记录是否有符合题意的p数组 
		for(int i=1; i<=n; i++) p[i]=i;//赋初值 
		for(int i=1; i<=n; i++){
			scanf("%d",&q[i]);
			if(q[i]<i) ok=1;//标记为无解。 
			//为啥无解呢?
			//那是因为:q数组的第i个是为p的前i个数中最大的。
			//又因为p为1~n中不重复的数字组成的数组。 
			//所以要是q[i]<i,就是无解。 
			else swap(p[i],p[q[i]]);//交换 
		}
		if(ok==1) printf("-1");//无解 
		else for(int i=1; i<=n; i++) printf("%d ",p[i]);
		printf("\n");//记得换行 
	} 
	return 0;
}
posted @   naroto2022  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
花开如火,也如寂寞。