您的位置:首页 > 其它

合唱队形2(洛谷U5874)

2016-11-16 21:45 162 查看

题目背景

上次老师挑出来的(N-K)位同学很不高兴,于是他们准备自己组建合唱队形。他们请了kkk来帮忙。

题目描述

他们安排了一个动作——手拉着手唱一首歌(就是他们围成一个圈)。如果有两个相邻的同学的身高差非常大(比如姚明和一个1.5米高的人站在一起)的话,评委会感觉非常不爽。于是kkk需要帮助他们求出一种排队方案,使他们身高差距最大值最小,并输出这个最小值和这个方案。

输入输出格式

输入格式:

第一行一个整数N表示有N个人(排成一个圈)

第二行N个整数表示每个人的身高

输出格式:

第一行一个整数表示最小的身高差距最大值

第二行N个整数表示这个最优方案,如果多解输出字典序最小

输入输出样例

输入样例#1

6

1 23 4 5 6


输出样例#1

2

1,2,4,6,5,3


说明

1<=N<=6000

1<=身高<=1000

/*
二分答案不用多说,重点是怎么判断。
刚开始看错题目了,以为是序号的字典序最小,然而是身高。那么现在就很好判断了,因为要字典序最小,所以我们先按身高排序,最小的肯定在第一位,然后尽量把身高小的按顺时针排,前提是他的下一个能够按逆时针排在下一位,因为我们还要连到末尾,这样贪心就是字典序最小。
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define N 6010
using namespace std;
int a
,n,l=N,r,q
,ans
;
bool check(int limit){
memset(q,0,sizeof(q));
q[1]=a[1];q[n+1]=a[1];int shun=1,ni=n+1;
for(int i=2;i<n;i++){
if(abs(a[i]-q[shun])<=limit&&abs(a[i+1]-q[ni])<=limit){
q[++shun]=a[i];
}
else if(abs(a[i]-q[ni])<=limit){
q[--ni]=a[i];
}
else return false;
}
if(abs(a
-q[shun])<=limit&&abs(a
-q[ni])<=limit){
q[shun+1]=a
;
return true;
}
return false;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
l=min(l,a[i]);
r=max(r,a[i]);
}
sort(a+1,a+n+1);
int tot=r;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid)){
tot=mid;r=mid-1;
for(int i=1;i<=n;i++)
ans[i]=q[i];
}
else l=mid+1;
}
printf("%d\n",tot);
for(int i=1;i<n;i++)
printf("%d,",ans[i]);
printf("%d",ans
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: