codeforces 1546C. AquaMoon and Strange Sort | 思维

题目链接:~~~


题目大意:
给 n 个数,每个数有一个权值 ai。有一个操作:每次可以交换两个相邻的数。
问:是否可以对每个数都进行偶数次操作,使得这个数升序。


分析:
第一点:一个数 ax 到它排序后的位置 y 需要的操作次数是一定的:| x - y | ,(ps:多换了没用,故意换到另一边,还需要再换回来
第二点:如果 x 和 y 同样是偶数或者奇数,| x - y | 的结果为偶数
第三点:根据一二,我们只需要判断一下是不是奇偶对应即可
第四点:对 x 和 y 模 2,这时 0 就是偶数 1 就是奇数,用 pair 存对应信息。把原数组排序前的信息存到 A中,再把原数组排序后的信息存到 B 中。对 A 和 B 排序,看对应位置的就是否相同即可。
ps:解释一下第四点最后排序的意义,在 A 和 B 中,0 表示偶数 1 表示奇数,对 A 和 B排序,就可以保证偶数在前,奇数在后。如果0对0,1对1,就表示满足操作次数为偶数,否则操作次数是奇数。
eg:
比如 A 中存储信息为:(15, 0),(15, 1), (15, 0),说明有三个 15 ,三个15中,两个在的偶数位,一个在奇数位
对 A 排序后变为:(15, 0) , (15, 0), (15, 1)。
这时,对原数组排序后,B 中存储的信息若为:(15, 1),(15, 0), (15, 0),说明排序后有三个 15 ,三个15中,两个在的偶数位,一个在奇数位
对 B 排序后为:(15, 0) , (15, 0), (15, 1)
A 和 B,相同,说明全部都是偶数次操作
若:B中的信息为:(15, 1),(15, 1), (15, 0),说明排序后有三个 15 ,三个15中,一个在的偶数位,两个在奇数位
对 B 排序后为:(15, 0) , (15, 1), (15, 1)
A 和 B,不相同,说明必须有一个15需要奇数次操作才能到达对应的位置


参考代码:

#include <vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#define ll long long
#define chushi(a, b) memset(a, b, sizeof(a))
#define endl "\n"
const double eps = 1e-8;
const ll INF=0x3f3f3f3f;
const int mod=1e9 + 7;
const int maxn = 5e5 + 5;
using namespace std;		

int a[maxn];

vector<pair<int, int> > x;
vector<pair<int, int> > y;

int main(){
	
	int ncase;
	cin >> ncase;
	
	while(ncase--){
		int n;
		cin >> n;
		for(int i = 1; i <= n; i++) cin >> a[i];
		for(int i = 1; i <= n; i++) x.push_back({a[i], i % 2});
		sort(a+1, a+1+n);
		for(int i = 1; i <= n; i++) y.push_back({a[i], i % 2});
		sort(x.begin(), x.end());
		sort(y.begin(), y.end());
		
		if(x == y) cout << "YES" << endl;
		else cout << "NO" << endl;
		
		x.clear();
		y.clear();
	}
	
	return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值