1. 程式人生 > >【CodeForces - 140C】New Year Snowmen (貪心)

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

題幹:

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, ..., r

n. 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

解題報告:

   貪心了半天發現貪錯了,,題目要求的是堆最多的雪人,不是堆最大的雪人(並且你這樣貪心出的方案也不是最大的)。

  所以我們應該按照同半徑的雪球數量排序然後再貪心、、

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 ;
 }