标签:构造法
1.题目描述:点击打开链接
2.解题思路:本题利用构造法解决。一开始想着暴力枚举,但n的范围太大,显然是不可取的。于是就观察给的样例,看如何构造出符合题意的排列。不幸的是,这道题在比赛结束前也没有弄对==。今天补题的时候又琢磨了一会儿终于过了。真是思维捉急的无话可说。下面回归正题。
本题可以先预处理n≤3的情况,对于之后的情况,分奇偶两种情况来处理。如果是偶数,那么首尾配对,每次交替前后顺序即可,比如n==6时,得到的序列是(1,6),(5,2),(3,4),然后从数组的中间向两边逐个填入每一对的元素,即3 5 1 6 2 4。当n为奇数时,中位数先放入数组中间,然后重复上述操作即可。
3.代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; #define N 5000+10 typedef pair<int, int>P; int a[N]; int n; int main() { //freopen("t.txt", "r", stdin); while (~scanf("%d", &n)) { vector<P>tmp; if (n <= 2){ printf("1\n1\n"); } else if (n == 3){ printf("2\n1 3\n"); } else{ int mid = (n + 1) / 2; for (int i = 1; i <= mid;i++) { if (n + 1 - i == i)continue; if (i & 1)tmp.push_back(P(i, n - i + 1)); else tmp.push_back(P(n - i + 1, i)); } int len = tmp.size(); if (n%2==0) for (int i = 0; i <len; i++) { a[len - 1 - i] = tmp[i].first; a[len + i] = tmp[i].second; } else { a[len] = mid;//先放入中位数 for (int i = 0; i < len; i++) { a[len - 1 - i] = tmp[i].first; a[len + 1 + i] = tmp[i].second; } } int cnt = (n & 1) ? 2 * len + 1 : 2 * len; printf("%d\n", cnt); for (int i = 0; i < cnt; i++) printf("%d%c", a[i], i == cnt - 1 ? '\n' : ' '); } } return 0; }
标签:构造法
原文地址:http://blog.csdn.net/u014800748/article/details/45023919