D1原题链接: https://codeforces.com/contest/1419/problem/D1
D1测试样例
input
5
1 2 3 4 5
output
2
3 1 4 2 5
D1Note
In the example it’s not possible to place ice spheres in any order so that Sage would buy 3 of them. If the ice spheres are placed like this (3,1,4,2,5), then Sage will buy two spheres: one for 1 and one for 2, because they are cheap.
D2原题链接: https://codeforces.com/contest/1419/problem/D2
D2测试样例
input
7
1 3 2 2 4 5 4
output
3
3 1 4 2 4 2 5
D2Note
In the sample it’s not possible to place the ice spheres in any order so that Sage would buy 4 of them. If the spheres are placed in the order (3,1,4,2,4,2,5), then Sage will buy one sphere for 1 and two spheres for 2 each.
题意: 有 n n n个冰球排成一排,它们都有着各自的价格,现在你认为若一个冰球左右两边的冰球价格均大于此该冰球价格,那么这个冰球就是便宜的。(最左边和最右边的冰球都是不便宜的。),现在你只想购买便宜的,问你怎样排序才能购买到最多的冰球。(D1中冰球价格都不相同,D2中冰球价格可以相同。)
D1解题思路: 对于D1,处理起来是比较简单的。我们首先要知道我们想要构造的是什么?两个大的夹个小的,使得这样的组合充分多。由于冰球的所有价格都是不同的,我们可以对它们进行排序,这样就大小分明了。组合是最重要的一步,我们想想,如果对半分开形成一个小数组一个大数组。再将小数组插在大数组中,这样得到的组合是不是最多的?显然是这样,这样我们可以最大化组合数为 ( n − 1 ) / 2 (n-1)/2 (n−1)/2,也就是我们可以购买的冰球数。故D1易解,具体看代码。
D1AC代码
/*
*邮箱:unique_powerhouse@qq.com
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include<bits/stdc++.h> //POJ不支持
#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair
using namespace std;
const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e5+3;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//
int n;
int ice[maxn];
int main(){
//freopen("in.txt", "r", stdin);//提交的时候要注释掉
IOS;
while(cin>>n){
rep(i,1,n){
cin>>ice[i];
}
sort(ice+1,ice+n+1);
cout<<(n-1)/2<<endl;
rep(i,1,n/2){
cout<<ice[i+n/2]<<" "<<ice[i]<<" ";
}
if(n&1)
cout<<ice[n]<<endl;
else
cout<<endl;
}
return 0;
}
D2解题思路: D2其实和D1一样,也是要插入,只不过现在价格是可以相同的,我们就要避免让价格相同的连着放在一起。那么我们这个时候就可以实现真正的插入了。先每隔一个冰球空位放一个递增的小冰球(即从小到大开始放冰球),放完之后再从大到小放冰球补空位,这样就可以避免价格相同的在一起,也最大化了可购买冰球的数量。OK,具体看代码。
D2AC代码(自然是可以A掉D1)
/*
*邮箱:unique_powerhouse@qq.com
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include<bits/stdc++.h> //POJ不支持
#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair
using namespace std;
const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e5+3;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//
int n;
int a[maxn];
int result[maxn];
int main(){
//freopen("in.txt", "r", stdin);//提交的时候要注释掉
IOS;
while(cin>>n){
rep(i,1,n){
cin>>a[i];
}
memset(result,0,sizeof(result));
int temp1=1,temp2=n;
sort(a+1,a+1+n);
//每隔一个冰球插一个小冰球。
for(int i=2;i<=n;i+=2){
result[i]=a[temp1++];
}
for(int i=n;i>=1;i--){
//现在对没有插入的冰球进行插入。
if(!result[i]){
result[i]=a[temp2--];
}
}
int ans=0;
rep(i,2,n-1){
if(result[i]<result[i-1]&&result[i]<result[i-1]){
ans++;
}
}
cout<<ans<<endl;
rep(i,1,n){
cout<<result[i]<<" ";
}
cout<<endl;
}
return 0;
}