CodeForces - 140C (贪心+优先队列+思维)

CodeForces - 140C (贪心+优先队列+思维)

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 n snowballs with radii equal to r1, r2, …, rn. To make a snowman, one needs any three snowballs whose radii are pairwise different. For example, the balls with radii 1, 2 and 3 can be used to make a snowman but 2, 2, 3 or 2, 2, 2 cannot. Help Sergey and his twins to determine what maximum number of snowmen they can make from those snowballs.

Input
The first line contains integer n (1 ≤ n ≤ 105) — the number of snowballs. The next line contains n integers — the balls’ radii r1, r2, …, rn (1 ≤ ri ≤ 109). The balls’ radii can coincide.

Output
Print on the first line a single number k — the maximum number of the snowmen. Next k 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.
Examples
Input
7
1 2 3 4 5 6 7
Output
2
3 2 1
6 5 4
Input
3
2 2 3
Output
0

题目大意:

有n个雪球,每个雪球都有个大小,只有三个不同大小的才能够堆成一个雪人,问这n个雪球,最多堆多少个雪人。

解题思路:

只有三个不同大小的雪球才能堆成雪人,所以我们应该先拿个数多的尺寸的雪球,这样拿完之后才能保证剩下的球不同尺寸的雪球最多。就比如 雪球的大小分别是 1 1 2 2 3 4 5如果我们先拿3 4 5 那剩下的不同尺寸的只有1 2 了 但是如果先拿1 2 3 那剩下的不同尺寸的还有5个,还能再堆一个雪人。这是这个题的关键贪心的地方。
具体的地方有一些细节处理

  • 我们怎么存雪球的尺寸+个数呢??这时候我们想到了用map<int,int>来存,因为这样最省空间,不然你得开一个1e9的数组,显然开不了这么大的数组
while(n--)
	{
		int t;
		cin>>t;
		mp[t]++;
	}
  • 我们怎么保证每次取得都是个数最多得三个呢??取完了之后他们得个数减一,总不能取一次排一次顺序吧? 所以我们想到了用优先队列,按个数排序 priority_queueq;
  • 我们队列放得是一个结构体,对结构体得优先队列,就得对<号进行重载,因为要对结构体排序嘛,我这里用的友元函数重载
friend bool operator <(node a,node b)///运算符c重载 
	{
		if(a.num!=b.num)
			return a.num<b.num;
		else
			return a.n<b.n;
	}
  • 因为输出要求是雪球尺寸从小到大得顺序输出,而我们从优先队列里取出来的是按数量从大到小来得,所以要对取出的结点,按尺寸大小排一下序放到答案数组里。
node a=q.top();
		q.pop();
		node b=q.top();
		q.pop();
		node c=q.top();
		q.pop();
		sum++;
		int tmp[3]={a.n,b.n,c.n};
		sort(tmp,tmp+3);
		A[cnt]=tmp[2];
		B[cnt]=tmp[1];
		C[cnt]=tmp[0];
		cnt++;
  • 我们取完了之后,还要判断一下这种尺寸得雪球是否还剩下,如果还有就加到优先队列里取。
AC代码:
#include <iostream>
#include <cstdio>
#include <queue>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
const int maxn=1e5+10;
int A[maxn];///储存答案得
int B[maxn];
int C[maxn];
map<int,int> mp;
class node{
public:
	int n;
	int num;
	node(int a=0,int b=0):n(a),num(b){}//构造函数
	friend bool operator <(node a,node b)///运算符c重载 
	{
		if(a.num!=b.num)
			return a.num<b.num;
		else
			return a.n<b.n;
	}
};
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		int t;
		cin>>t;
		mp[t]++;
	}
	priority_queue<node>q;
	map<int,int>::iterator it;
	for(it=mp.begin();it!=mp.end();it++)///把map里得东西加入优先队列
	{
		q.push(node(it->first, it->second));
	}
	if(q.size()<3)
	{
		cout<<"0"<<endl;
		return 0;
	}
	int sum=0;
	int cnt=0;
	while(q.size()>=3)
	{
		node a=q.top();
		q.pop();
		node b=q.top();
		q.pop();
		node c=q.top();
		q.pop();
		sum++;
		int tmp[3]={a.n,b.n,c.n};
		sort(tmp,tmp+3);
		A[cnt]=tmp[2];
		B[cnt]=tmp[1];
		C[cnt]=tmp[0];
		cnt++;
		if(a.num-1>0)
			q.push(node(a.n,a.num-1));
		if(b.num-1>0)
			q.push(node(b.n,b.num-1));
		if(c.num-1>0)
			q.push(node(c.n,c.num-1));
	}
	cout<<sum<<endl;
	for(int i=0;i<cnt;i++)
	{
		cout<<A[i]<<" "<<B[i]<<" "<<C[i]<<endl;
	}
	return 0;

}

猜你喜欢

转载自blog.csdn.net/weixin_43179892/article/details/84872727