传送门
题意
t组样例,每次给出n,求【1 2 … n】排列后满足前后相差在2-4之间,输出任意一种情况。
分析
刚拿到题目的时候一头雾水,手推了几组没什么头绪。突然试了试样例里的n=4那组,发现了一些规律。
样例给出的是【3 1 4 2】,如果后续四个,会得到【3 1 4 2 7 5 8 6】,显然,2与7相差为5,不符合题意。
然而,将这四个数倒过来,得到【2 4 1 3】,就会惊奇的发现,后面只要四个一组的续,就都满足条件,比如【2 4 1 3 6 8 5 7】,当然,这只是n%4=0的情况。
显然,在n%4=1时,可以直接接上最后一位输出,比如【2 4 1 3 5】。
而在n%4=2时,将多余的两个数按从小到大的顺序插入最后一组最后一个数的两侧即可,例如【2 4 1 5 3 6】。
在n%4=3时,假设多余的数是a,b,c(a<b<c),则可以发现,将a,c按顺序插入最后一组最后一个数左侧,b留在末尾,就能得到符合要求的答案,比如【2 4 1 5 7 3 6】。
当然,要注意的是,在n<4时是不可能有符合要求的情况的。
规律寻找完毕,直接写出代码就可以ac了~
为了方便执行多余数字的插入,建议少些一组数字,直接用特殊规律填,详见代码a b c数组。
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void sxseven();
int main(){
ios::sync_with_stdio(0);
sxseven();
return 0;
}
const int N=1e3+5;
int a[4]={2,4,1,3};
int b[6]={2,4,1,5,3,6};
int c[7]={2,4,1,5,7,3,6};
void sxseven(){
int T;cin >> T;
while(T--){
int n;cin >> n;
if(n<4) cout << -1;
else if(n%4==0){
for(int i=0;i<n;i+=4){
for(int j=0;j<4;++j){
cout << a[j]+i << ' ';
}
}
}else if(n%4==1){
n--;
for(int i=0;i<n;i+=4){
for(int j=0;j<4;++j){
cout << a[j]+i << ' ';
}
}
cout << n+1;
}else if(n%4==2){
n-=6;
for(int i=0;i<n;i+=4){
for(int j=0;j<4;++j){
cout << a[j]+i << ' ';
}
}
for(int i=0;i<6;++i){
cout << n+b[i] << ' ';
}
}else{
n-=7;
for(int i=0;i<n;i+=4){
for(int j=0;j<4;++j){
cout << a[j]+i << ' ';
}
}
for(int i=0;i<7;++i){
cout << n+c[i] << ' ';
}
}
cout <<endl;
}
}