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