CF786-D ABC-SORT

Problem - D - Codeforces

贪心。

从A的末端插到B的中间,再从B的中间插到C的末端。

可以证明,A->B的过程中,插到中间的左边,和右边的结果是一样的

又因为A->B先插入的,B->C先取出。B->C若长度为偶数可以从中间两个中取较小的。

所以只考虑末尾的两个数即可,使用vector进行插入和删除操作,由于只对末尾进行操作,故复杂度为O(n)

最后检查是否为non-decreasing即可

代码如下

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<iomanip>
#include<cstring>
#include<climits>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;

#define go(i,a,b) for(int i=a;i<=b;++i)
#define com(i,a,b) for(int i=a;i>=b;--i)
#define mem(a,b) memset(a,b,sizeof(a))
#define fo(i,a) for(int i=0;i<a;++i)

typedef long long ll;

const int N = 2e5 + 5;

typedef vector<int> vec;
int a[N];

int main() {
	int T;
	cin >> T;
	int n;
	while (T--) {
		cin >> n;
		vec b, c;
		bool flag = 1;
		go(i, 1, n) {
			cin >> a[i];
		}
		for (int i = n; i >= 1; --i) {
			int len = n - i;
			b.push_back(a[i]);//从尾部先出
			//可以证明,无论是插左边还是插右边,其实都是等价的
		}
		int l = n;
		while (l) {
			if (l % 2 == 0) {
				if (b[l - 1] < b[l - 2]) {
					c.push_back(b[l - 1]);
					b.pop_back();
				}
				else {
					c.push_back(b[l - 2]);
					b.erase(b.begin() + l - 2);
				}
			}
			else {
				c.push_back(b[l - 1]);
				b.pop_back();
			}
			--l;
		}
		for (int i = 1; i < n; ++i) {
			if (c[i] < c[i - 1]) {
				cout << "NO" << endl;
				flag = 0;
				break;
			}
		}
		if (flag == 1)
			cout << "YES" << endl;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值