现在有 n 个数,对 a[] 重新排序,使得好数最多
好数的定义:在数组中比相邻的两个数都小,则称为好数,当然数组最左边和最右边的数不能称之为好数
可以保证在数组 a 中,可能会有几个数相等
题目一定是要进行插空的,偶数的位置放小数,但是 n 为偶数的时候,会有一个小数在最后的位置浪费掉,先将最后一个数用最大数填上,这样剩下奇数个位置
贪心策略:因为要避免相同的数,所以 a 数组先在偶数位置处从小到大放置数据,再在奇数位置处,从小到大放置数据
但 Wrong 了,因为最后两个位置都无法对答案做出贡献
比如 a 数组为:1 1 2 4
Wrong 代码:
const int N=1e5+5;
int n,m,t;
int i,j,k;
int a[N],b[N];
int main()
{
IOS;
while(cin>>n){
for(i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
int flag=0;
if(n%2==0){
b[n]=a[n];
n--;
flag=1;
}
int p=n;
for(i=1;i<=n;i+=2){
b[i]=a[p];
p--;
}
int ans=0;
for(i=2;i<=n;i+=2){
b[i]=a[p--];
if(b[i]<b[i-1] && b[i]<b[i+1]) ans++;
}
cout<<ans<<endl;
for(i=1;i<=n;i++) cout<<b[i]<<" ";
if(flag) cout<<b[n+1];
cout<<endl;
}
//PAUSE;
return 0;
}
为了避免上述情况的发生,不需要考虑奇偶,直接按照贪心策略放置即可
AC 代码:
const int N=1e5+5;
int n,m,t;
int i,j,k;
int a[N],b[N];
int main()
{
IOS;
while(cin>>n){
for(i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
int p=1;
for(i=2;i<=n;i+=2){
b[i]=a[p];
p++;
}
for(i=1;i<=n;i+=2){
b[i]=a[p];
p++;
}
int ans=0;
for(i=2;i<n;i++){
if(b[i]<b[i-1] && b[i]<b[i+1]) ans++;
}
cout<<ans<<endl;
for(i=1;i<=n;i++) cout<<b[i]<<" ";
cout<<endl;
}
//PAUSE;
return 0;
}