专栏文章

题解:CF2023A Concatenation of Arrays

CF2023A题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqaa5e1
此快照首次捕获于
2025/12/04 01:31
3 个月前
此快照最后确认于
2025/12/04 01:31
3 个月前
查看原文

分析

可以看出,我们有几种排序方式。

第一种:比较两个数组之间相互逆序对大小。
例如:
数组 a1a1a2a2cnt1cnt1 个逆序对。
数组 a2a2a1a1cnt2cnt2 个逆序对。
比较 cnt1cnt1cnt2cnt2 大小来排序。

第二种:看哪个数组有两个数组最大值,那个数组就排在后面。
例如:
数组 a1a1 元素为 [2,3][2,3],数组 a2a2 元素为 [1,5][1,5]
因为数组 a2a2 中有两个数组最大值:55,因此将 a2a2 排在 a1a1 后面。

第三种:按和排序。
例如:
数组 a1a1 元素为 [2,3][2,3],和为 55;数组 a2a2 元素为 [1,5][1,5],和为 66
因为 6>56 > 5,因此将 a2a2 排在 a1a1 后面。

证明对错:

第一种:
由于比较两个数组之间相互逆序对大小并不能推向全局,贪心思想必须有传递性,于是废除。
例子:
a1=(3,3)a1 = (3,3)a2=(1,5)a2 = (1,5)a1=(2,2)a1 = (2,2)
由于 a1a1a2a2 逆序对数量都为 22,我们将 a2a2 排在 a1a1 后面,a2a2a3a3 逆序对数量都为 22,我们将 a3a3 排在 a2a2 后面。
于是就有了以下一个序列:
(3,3,1,5,2,2)(3,3,1,5,2,2)
明显不是最优。

第二、三种都具有传递性,所以都可以作为答案。

Code

CPP
#include<bits/stdc++.h>
using namespace std;
pair<int,int> a[100010];
inline int read() {
	int x=0,f=1;
	char ch=getchar/*_unlocked*/();
	while (ch<48||ch>57) {
		if (ch=='-') f=-1;
		ch=getchar/*_unlocked*/();
	}
	while (ch>=48&&ch<=57) {
		x=x*10+ch-48;
		ch=getchar/*_unlocked*/();
	}
	return x*f;
}

template<typename T>
inline void write(T x,int f=1) {
	if(x<0) putchar/*_unlocked*/('-'),x=-x;
	if(x>9) write(x/10,0);
	putchar/*_unlocked*/(x%10+'0');
	if(f==1)putchar/*_unlocked*/('\n');
	if(f==2) putchar/*_unlocked*/(' ');
	return;
}

bool cmp(pair<int,int> x,pair<int,int> y) {
	int a=x.first,a1=x.second,b=y.first,b1=y.second;
	int maxn=max({a,a1,b,b1});
	if((a==maxn||a1==maxn)&&(b==maxn||b1==maxn)) return (a+a1)<(b+b1);
	else if(a==maxn||a1==maxn) return 0;
	else if(b==maxn||b1==maxn) return 1;
}
int  main() {
	int t=read();
	while(t--) {
		int n=read();
		int cnt=0;
		for(register int i = 1; i <= n; i++) a[i]= {read(),read()};
		sort(a+1,a+n+1,cmp);
		for(register int i = 1; i <= n; i++) cout<<a[i].first<<' '<<a[i].second<<' ';
		cout<<'\n';
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...