洛谷CF1741B Funny Permutation

题目描述

如果一个长度为 n的数列满足恰好包含 11 到 n 的整数各一个,则我们称之为排列。例如,[3,1,4,2][3,1,4,2]、[1][1] 和 [2,1][2,1] 都是排列,但是 [1,2,1][1,2,1]、[0,1][0,1] 和 [1,3,4][1,3,4] 都不是。

给你一个 nn,你需要构造一个长度为 nn 的排列 pp,使得它同时满足以下两个要求:

  1. \forall 1 \leq i \leq n∀1≤i≤n,都至少有一个邻居(p_ipi​ 的邻居为 p_{i + i}pi+i​ 和 p_{i - 1}pi−1​),使其值为 p_i + 1pi​+1 或 p_i - 1pi​−1。

  2. \forall 1 \leq i \leq n∀1≤i≤n,都有 p_i \ne ipi​=i。

我们称同时符合以上两个要求的排列为“有趣的排列”。

例如,当 n = 4n=4 时,[4,3,1,2][4,3,1,2] 是一个“有趣的排列”,因为:

  • p_2 = p_1 - 1 = 4 - 1 = 3p2​=p1​−1=4−1=3;
  • p_1 = p_2 + 1 = 3 + 1 = 4p1​=p2​+1=3+1=4;
  • p_4 = p_3 + 1 = 1 + 1 = 2p4​=p3​+1=1+1=2;
  • p_3 = p_4 - 1 = 2 - 1 = 1p3​=p4​−1=2−1=1;
  • \forall 1 \leq i \leq n∀1≤i≤n,都有 p_i \ne ipi​=i。

给定一个 nn,你需要构造出一个长度为 nn 的“有趣的排列”,或者输出一个 -1−1 来表明不存在长度为 nn 的“有趣的排列”。

输入格式

第一行,输入一个正整数 t(1 \leq t \leq 10^4t(1≤t≤104,表示数据组数。

接下来 tt 行,每行一个正整数 n(2 \leq n \leq 2 \times 10^5)n(2≤n≤2×105),表示你需要构造一个长度为 nn 的“有趣的排列”。

数据保证 \sum{n} \leq 2 \times 10^5∑n≤2×105。

输出格式

对于每组测试数据,输出任意一个长度为 nn 的“有趣的排列,或者输出一个 -1−1——如果这根本不可能。

输入输出

代码:

#include<iostream>
using namespace std;
//定义一个很大的全局变量,为数组开拓空间
const int N=1e5+7;
int a;
int c[N];
int main(){
	cin>>a;
	for(int i=0;i<a;i++){
		cin>>c[i];
	}
	for(int m=0;m<a;m++){
		int f[c[m]];
		if(c[m]==3){
			cout<<"-1"<<endl;
		}else if(c[m]==1){
			cout<<"1"<<endl;
		}else if(c[m]==2){
			cout<<"2 1"<<endl;
		}else{
			f[0]=c[m]-1;
			f[1]=c[m];
			for(int i=2,j=1;i<c[m];i++,j++){
				f[i]=j;
			}
			for(int i=0;i<c[m];i++){
				cout<<f[i]<<" ";
			}
			cout<<endl;
		}
	}
}

 投机取巧篇,

题目中已给出长度为3的数列不能构成有趣数列段,所以提前排除,而为1,2的只有题目中给到的情况,所以提前写出,

文中只要求写出任意一个满足情况的数列,根据规律发现把数段的前两个的设置之后其他的可以按数字大小顺序从大到小或从小到大排列(1到c[m]-2),而前两个为了满足题意中的前后至少有一个是 q+1,or q-1;所以只需要把q-1放在q的前面即可。(q和q-1不调换顺序也可,但是当n为4时要单独写出{若不写出,则有可能会输出4 3 2 1的情况}) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值