【CodeForces - 140C】New Year Snowmen (贪心)

版权声明:欢迎学习我的博客,希望ACM的发展越来越好~ https://blog.csdn.net/qq_41289920/article/details/84557647

题干:

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

扫描二维码关注公众号,回复: 4423500 查看本文章
0

解题报告:

   贪心了半天发现贪错了,,题目要求的是堆最多的雪人,不是堆最大的雪人(并且你这样贪心出的方案也不是最大的)。

  所以我们应该按照同半径的雪球数量排序然后再贪心、、

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
typedef pair<int,int> pii;
map<int,int> mp;
map<int,int> :: iterator it;
int ans1[MAX],ans2[MAX],ans3[MAX];
int tot;
int main()
{
	priority_queue<pii> pq;
	int n;
	cin>>n;
	int tmp;
	for(int i = 1; i<=n; i++) {
		scanf("%d",&tmp);mp[tmp]++;
	}
	for(it = mp.begin(); it!=mp.end(); ++it) {
		pq.push(pm(it->se,it->fi));
	}
	while(pq.size() >= 3) {
		pii q1,q2,q3;
		q1=pq.top();pq.pop();
		q2=pq.top();pq.pop();
		q3=pq.top();pq.pop();
		ans1[++tot] = q1.se;
		ans2[tot] = q2.se;
		ans3[tot] = q3.se;
		if(q1.fi>1) pq.push(pm(q1.fi-1,q1.se));
		if(q2.fi>1) pq.push(pm(q2.fi-1,q2.se));
		if(q3.fi>1) pq.push(pm(q3.fi-1,q3.se));
	}
	for(int i = 1; i<=tot; i++) {
		
	}
	printf("%d\n",tot);
	int x[3];
	for(int i = 1,x1,x2,x3; i<=tot; i++) {
		x[0]=ans1[i],x[1]=ans2[i],x[2]=ans3[i];
		sort(x,x+3);
		printf("%d %d %d\n",x[2],x[1],x[0]);
	}

	return 0 ;
 }

错误代码:(没眼看了)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
set<ll> ss;
set<ll> :: iterator it;
int main()
{
	int n;
	cin>>n;
	ll tmp;
	for(int i = 1; i<=n; i++) {
		scanf("%lld",&tmp);ss.insert(tmp);
	}
	int ans = ss.size()/3;
	printf("%d\n",ans);
	int cur = 0;
	it = ss.end();--it;
	while(1) {
		if(cur >= ans) break;
		printf("%lld ",*it);
		--it;
		printf("%lld ",*it);
		it--;
		printf("%lld\n",*it);
		--it;
		cur++;
	}
	return 0 ;
 }

错误代码2:(这个是还能过几个样例的)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
set<int> ss;
multiset<int> mss;
set<int> :: iterator sit;
multiset<int> ::iterator msit;
int ans1[MAX],ans2[MAX],ans3[MAX];
int main()
{
	int n;
	cin>>n;
	int tmp;
	for(int i = 1; i<=n; i++) {
		scanf("%d",&tmp);ss.insert(tmp);mss.insert(tmp);
	}
	int cur = 0;
	sit = ss.end();--sit;
	while(1) {
		if(ss.size() < 3) break;
		sit = ss.end();--sit;
		ans1[++cur] = *sit;//printf("%lld ",*sit);
		mss.erase((mss.find(*sit)));
		if(mss.find(*sit) == mss.end()) {
			ss.erase(*sit);sit=ss.end();--sit;
		}else --sit;
		ans2[cur] = *sit;//printf("%lld ",*sit);
		mss.erase((mss.find(*sit)));
		if(mss.find(*sit) == mss.end()) {
			ss.erase(*sit);sit=ss.end();--sit;
		}else --sit;
		ans3[cur] = *sit;//printf("%lld\n",*sit);
		mss.erase((mss.find(*sit)));
		if(mss.find(*sit) == mss.end()) ss.erase(*sit);
		
//		printf("%d %d %d\n",ans1[cur],ans2[cur],ans3[cur]);
	}
	//但是其实这么贪心的话就不需要加虾米那这几行代码了, 虽然贪心也不对,并且贪错东西了
//	for(int i = 1; i<=cur; i++) {
//            if(ans1[i] < ans2[i]) swap(ans1[i], ans2[i]);  //别忘记这一步。。。
//            if(ans1[i] < ans3[i]) swap(ans1[i], ans3[i]);
//            if(ans2[i] < ans3[i]) swap(ans2[i], ans3[i]);
//       }
	printf("%d\n",cur);
	for(int i = 1; i<=cur; i++) {
		printf("%d %d %d\n",ans1[i],ans2[i],ans3[i]);
	}
	return 0 ;
 }
/*
6
1 1 2 2 3 3

*/

总结:   

   刚开始因为没看见要排序wa了一发。。。(其实是感觉已经排好序了但是其实并没有,,因为你是贪心的数量最多啊)。

再贴一个巨佬的思路:(用的是二分)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
int a[MAX];
int n,ans[MAX];
bool ok(int x) {
	int cur=0;
	for(int i = 1; i<=n; i++) {
		if(cur < x || a[i] > ans[cur-x]) ans[cur++] = a[i];
	}
	return cur >= 3*x;
}
int main()
{
	cin>>n;
	for(int i = 1; i<=n; i++) scanf("%d",a+i);
	sort(a+1,a+n+1);
	int l = 0,r = n;
	int mid = (l+r)/2;
	int aans;
	while(l<=r) {
		mid = (l+r)>>1;
		if(ok(mid)) l=mid+1,aans=mid;
		else r=mid-1;
	}
	printf("%d\n",aans);
	ok(aans);
	for(int i = 0; i<aans; i++) {
		printf("%d %d %d\n",ans[i+2*aans],ans[i+aans],ans[i]);
	}

	return 0 ;
 }

猜你喜欢

转载自blog.csdn.net/qq_41289920/article/details/84557647