码迷,mamicode.com
首页 > 其他好文 > 详细

#298 (div.2) A. Exam

时间:2015-04-13 14:45:52      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:构造法

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;
}

#298 (div.2) A. Exam

标签:构造法

原文地址:http://blog.csdn.net/u014800748/article/details/45023919

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!