首页 > 代码库 > 合唱队形2(洛谷U5874)
合唱队形2(洛谷U5874)
题目背景
上次老师挑出来的(N-K)位同学很不高兴,于是他们准备自己组建合唱队形。他们请了kkk来帮忙。
题目描述
他们安排了一个动作——手拉着手唱一首歌(就是他们围成一个圈)。如果有两个相邻的同学的身高差非常大(比如姚明和一个1.5米高的人站在一起)的话,评委会感觉非常不爽。于是kkk需要帮助他们求出一种排队方案,使他们身高差距最大值最小,并输出这个最小值和这个方案。
输入输出格式
输入格式:
第一行一个整数N表示有N个人(排成一个圈)
第二行N个整数表示每个人的身高
输出格式:
第一行一个整数表示最小的身高差距最大值
第二行N个整数表示这个最优方案,如果多解输出字典序最小
输入输出样例
输入样例#1:
6
1 2 3 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],n,l=N,r,q[N],ans[N]; 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[n]-q[shun])<=limit&&abs(a[n]-q[ni])<=limit){ q[shun+1]=a[n]; 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[n]); return 0; }
合唱队形2(洛谷U5874)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。