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