C. Parity Shuffle Sorting(思维/贪心)

题目

题意

在这里插入图片描述
给定一个数组,选择操作下标l,r,
如果它们和为偶数,则令a[l]=a[r];
如果它们和为奇数,则令a[r]=a[l];

现给定一个数组,问如何构造,使得最终数组为非递减。
即a[1]<=a[2]<=…<=a[n]

要求操作次数不超过n

思路

可以把它们变成全部相同的元素。
统计 同奇偶性 的数据块。

让最后一个奇数位置上的数据块,做为汇总点。

  • 将前面的奇数块,都朝它汇总
  • 将偶数位置上的数据块,朝与它左边相邻的奇数位置的数据块汇总

C. Parity Shuffle Sorting(思维/贪心)_第1张图片

代码

#include
using namespace std;
#define ll long long
#define pii pair
#define fir first
#define sec second
#define all(x) (x).begin(), (x).end()
const int maxn = 200010;
#define inf 1e18

int n, a[maxn];
void print_p(vector<pii>& ve) {
	printf("%d\n", ve.size());
	for (auto p: ve) {
		printf("%d %d\n", p.fir, p.sec);
	}
}
void solve() {
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &a[i]);
		a[i] %= 2;
	}
	vector<pii> ve;
	ve.push_back({1, 1});
	int tot = 0;
	for (int i = 2; i <= n; ++i) {
		if (a[i] == a[ve[tot].sec]) {
			ve[tot].sec = i;
		} else {
			ve.push_back({i, i});
			++tot;
		}
	}
//	printf("ve:\n");// debug
//	print_p(ve);// debug
//	printf("--------\n");// debug
	vector<pii> res;
	int st;
	if (tot & 1) { // even length of pairs
		st = tot - 1;
	} else { // odd length of pairs
		st = tot;
	}
	for (int i = ve[st].fir; i <= ve[st].sec - 1; ++i) {
		res.push_back({i, ve[st].sec});
	}
	for (int k = st - 2; k >= 0; k -= 2) {
		for (int i = ve[k].fir; i <= ve[k].sec; ++i) {
			res.push_back({i, ve[st].sec});
		}
	}
	for (int k = st + 1; k >= 1; k -= 2) {
        if (k > tot) continue;
		for (int i = ve[k].fir; i <= ve[k].sec; ++i) {
			res.push_back({ve[k-1].sec, i});
		}
	}
	print_p(res);
}

int main() {
	int t;
	scanf("%d", &t);
//	t = 1; 
	while (t--) {
		solve();
	}
}
/*
99
4
1 2 3 4
5
1 2 3 4 5
8
1 1 2 2 3 3 4 4
10
1 1 2 2 3 3 4 4 5 5

*/

你可能感兴趣的:(Codeforces,算法)