CF140C New Year Snowmen (#贪心+优先队列)

32 篇文章 2 订阅
31 篇文章 0 订阅

题意翻译

现在来做雪人,每个雪人由三个不同大小的雪球构成:一个大的,一个中等的,一个小的。现在有nn个雪球半径分别为r_1, r_2, ..., r_nr1​,r2​,...,rn​为了做雪人,三个雪球的大小必须两两不同。例如,半径分别为 1,2,31,2,3 的雪球可以做成雪人,但2,2,32,2,3或2,2,22,2,2不行。现在需要尽可能做更多雪人。

Input

第一行是一个整数n(1<=n<=10^5)n(1<=n<=105)雪球的数量. 接下来有n行整数 — 雪球的半径r_1, r_2, ..., r_n(1<=r_i<=10^9)r1​,r2​,...,rn​(1<=ri​<=109)

Output

第一行是一个数kk最大的雪人数. 接下来kk行是每个雪人的描述大雪球的半径,中等雪球的半径,小雪球的半径. 允许按任意顺序输出雪人描述. 如果有多种方案,输出任意一个

题目描述

As meticulous Gerald sets the table and caring Alexander sends the postcards, Sergey makes snowmen. Each showman should consist of three snowballs: a big one, a medium one and a small one. Sergey's twins help him: they've already made nn snowballs with radii equal to r_{1}r1​ , r_{2}r2​ , ..., r_{n}rn​ . To make a snowman, one needs any three snowballs whose radii are pairwise different. For example, the balls with radii 11 , 22 and 33can be used to make a snowman but 22 , 22 , 33 or 22 , 22 , 22 cannot. Help Sergey and his twins to determine what maximum number of snowmen they can make from those snowballs.

输入输出格式

输入格式:

The first line contains integer nn ( 1<=n<=10^{5}1<=n<=105 ) — the number of snowballs. The next line contains nnintegers — the balls' radii r_{1}r1​ , r_{2}r2​ , ..., r_{n}rn​ ( 1<=r_{i}<=10^{9}1<=ri​<=109 ). The balls' radii can coincide.

输出格式:

Print on the first line a single number kk — the maximum number of the snowmen. Next kk lines should contain the snowmen's descriptions. The description of each snowman should consist of three space-separated numbers — the big ball's radius, the medium ball's radius and the small ball's radius. It is allowed to print the snowmen in any order. If there are several solutions, print any of them.

输入输出样例

输入样例#1

7
1 2 3 4 5 6 7

输出样例#1

2
3 2 1
6 5 4

输入样例#2

3
2 2 3

输出样例#2

0

思路

一开始没好好读题,还以为排个序就ok了,没想到相同半径雪球的个数是大于1的。。

写完以后,发现自己输出的和样例输出不一样,还纠结好长时间,没看到这个是SPJ。存在多种答案的......

首先3个不同大小的雪球才能构成一个雪人,所以我们要尽量先拿半径相同个数多的雪球,这样等拿完后可以尽量剩下不同尺寸的雪球更多。

为了使每次都能取最多的雪球,用了一下合并果子那题的思想,用优先队列按个数排序。

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
struct lxydl//雪球信息 
{
	long long int num,r;//num是相同尺寸的个数,r是半径 
	bool friend operator < (lxydl aa,lxydl bb)//默认从大到小排序,按数量排(贪心) 
	{
		return aa.num<bb.num;
	}
};
lxydl data;
typedef struct
{
	long long int a,b,c;
}snowball;//这个是预选的雪球组 
snowball sb[100001];
long long int n,s,cnt,a[100001],b[100001],c[100001];//a数组是读入的雪球半径,b数组是每种雪球的个数,c数组是每种雪球的大小 
priority_queue<lxydl> que;//拿优先队列来维护 
inline void change(long long int &x,long long int &y,long long int &z)//将3个元素从大到小排序 
{
	if(x<y)
		swap(x,y);
	if(x<z)
		swap(x,z);
	if(y<z)
		swap(y,z);
	return;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	register int i,j;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	sort(a+1,a+n+1);//将雪球排序,a数组只要是有序的就行 
	for(i=1,j=0;i<=n;i++)//这里离散化了一下 
	{
		if(a[i]==a[i-1])//如果前后雪球大小相同 
		{
			b[j]++;//统计当前大小相同雪球个数+1 
		}
		else//如果不相同 
		{
			b[++j]++;//b数组换一位,然后统计 
			c[j]=a[i];//记录雪球大小 
		}
	}
	for(i=1;i<=j;i++)//统计元素入队 
	{
		data.num=b[i];//读取当前大小雪球数量 
		data.r=c[i];//读取当前学大小 
		que.push(data);//入队 
	}
	while(que.size()>=3)
	{
		lxydl xsy=que.top();que.pop();//读取3个雪球 
		lxydl wwz=que.top();que.pop();
		lxydl lxy=que.top();que.pop();
		s++;//算符+1 
		xsy.num--;//每个雪球数量-1 
		wwz.num--;
		lxy.num--;
		sb[s].a=xsy.r;//记录半径 
		sb[s].b=wwz.r;
		sb[s].c=lxy.r;
		change(sb[s].a,sb[s].b,sb[s].c);//3个雪球大小从大往小排,变成严格递减数 
		if(xsy.num>0) que.push(xsy);//如果还有剩余的话,继续入队 
		if(wwz.num>0) que.push(wwz);
		if(lxy.num>0) que.push(lxy);
	}
	cout<<s<<endl;
	for(i=1;i<=s;i++)
	{
		cout<<sb[i].a<<' '<<sb[i].b<<' '<<sb[i].c<<endl;
	}
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值