码迷,mamicode.com
首页 > 其他好文 > 详细

## CF1352G Special Permutation

时间:2020-06-10 19:36:42      阅读:68      评论:0      收藏:0      [点我收藏+]

标签:inline   pre   else   奇数   没有   数据   构造   printf   scan   

CF1352G Special Permutation

一道巧妙的构造题。
首先对于\(n<4\),经过手算可以发现是没有这样的一组数据的。那么也就是找找\(n \geq 4\)的情况。

注意到这道题构造的特点是\(2\leq|p_i-p_{i+1}|\leq 4\)。那么\(2\)\(4\)是什么呢?构造题按照套路奇偶性一般都是要考虑的。那么\(2\)其实就是相邻两个奇(偶)数的差,\(4\)也就是中间隔着一个的两个奇(偶)数的差。

举个例子,当\(n=9\)时,奇数有\(1,3,5,7,9\),偶数有\(2,4,6,8\)。不妨考虑先把奇数从小到大排好,这样每两个数的差都是\(2\),满足条件。如果我们之后再将偶数从大到小排序,构成\(1,3,5,7,9,8,6,4,2\),中间两个数的差就是\(1\),显然不满足。这时如果我们将\(6,8\)交换位置,原数列变成了\(1,3,5,7,9,6,8,4,2\)就可以了。

\(n=10\)时,奇数有\(1,3,5,7,9\),偶数有\(2,4,6,8,10\)。这时先排奇数不行了,我们考虑先排偶数再排奇数。\(1,3,5,7,9,10,8,6,4,2\)。这样的话按照之前的策略交换\(8,10\)也是可以满足的,交换以后的数列变成\(1,3,5,7,9,8,10,6,4,2\)

于是总的策略就是先分奇偶,再按照上面的方法进行构造。

代码:

#include<bits/stdc++.h>
using namespace std;
int t;
void work1(int x)
{
	for(int i = 2; i <= x; i += 2) printf("%d ", i);
	printf("%d %d ", x - 3, x - 1);
	for(int i = x - 5; i >= 1; i -= 2) printf("%d ", i);
	printf("\n");
}
void work2(int x)
{
	for(int i = 1; i <= x; i += 2) printf("%d ", i);
	printf("%d %d ", x - 3, x - 1);
	for(int i = x - 5; i >= 2; i -= 2) printf("%d ", i);
	printf("\n");
}
int main()
{
	scanf("%d", &t);
	while(t --)
	{
		int n;
		scanf("%d", &n);
		if(n < 4) printf("-1\n");
		else
		{
			if(n % 2 == 0) work1(n);
			if(n % 2 == 1) work2(n);
		}
	}
}

## CF1352G Special Permutation

标签:inline   pre   else   奇数   没有   数据   构造   printf   scan   

原文地址:https://www.cnblogs.com/lcezych/p/13087285.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!