题目描述 Description
将1到N的整数数列(1,2,3,……,N)打乱,变为数列a(a[1],a[2],a[3],……,a[N])。如果这个数列对于任意的i∈{1,2,3,……,N}都满足a[a[i]]=N+1-i,则这个数列叫做长度为N的Queen数列。
现给你长度N,请输出字典序最小的Queen数列。
所谓字典序最小,即为a[1]最小,在此基础上a[2]最小,在此基础上a[3]最小……
输入描述 Input Description
共一行,为一个整数N。
输出描述 Output Description
共一行,有i个整数,以空格隔开(行尾没有空格),第i个整数为a[i]。其中a为字典序最小的长度为N的Queen数列。如果不存在这样的数列,请输出一个0。
样例输入 Sample Input
Input1:
3
Input2:
4
Input3:
5
样例输出 Sample Output
Output1:
0
Output2:
2 4 1 3
Output3:
2 5 3 1 4
数据范围及提示 Data Size & Hint
不存在长度为3的Queen数列。
2 4 1 3为字典序最小的长度为4的Queen数列。
2 5 3 1 4为字典序最小的长度为5的Queen数列。
对于20%的数据,N≤10;对于50%的数据,N≤1000;对于100%的数据,1≤N≤200000。
/* 一看题,好像没有什么头绪,标签竟然是搜索,好吧,那就打个搜索,全排列枚举在判断,n》10就超时了 分析n<10数列的规律 0 0 0 2 4 1 3 2 5 3 1 4 0 0 2 8 4 6 3 5 1 7 2 9 4 7 5 3 6 1 8 0 原来 if n mod 4>1 then begin writeln(0); halt; end; 而且一头一尾之和相等,于是搜索二分,时间复杂度减半,不过还是搜索 减半后 n范围可以到20 再拿20分析 2 20 4 18 6 16 8 14 10 12 9 11 7 13 5 15 3 17 1 19 就可以找出规律 */ #include<iostream> #include<cstdio> using namespace std; #define maxn 200010 int n,a[maxn]; int main(){ scanf("%d",&n); if(n%4>1){cout<<0;return 0;} for(int i=1;i<=n/4;i++){ a[2*i-1]=2*i; a[2*i]=n+2-2*i; a[n-2*i+2]=n+1-2*i; a[n-2*i+1]=2*i-1; } if(n%2==1)a[n/2+1]=(n+1)/2; for(int i=1;i<=n;i++)printf("%d ",a[i]); }