D1.D2 Sage‘s Birthday (easy version and hard version)(构造+思维) Codeforces Round #671 (Div. 2)

127 篇文章 3 订阅
24 篇文章 3 订阅

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 (n1)/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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HeZephyr

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值