CodeForces 140C New Year Snowm

题目链接:http://codeforces.com/contest/140/problem/C

题目大意:

  给定n个数组成的序列(有重复),从中选3个数为一组,使得这三个数严格递增,请问最多能选出多少组,把每组数据输出。

分析:

  很明显是贪心,不过贪心策略有待斟酌。

  一开始我想当然的把数据按大小排序后从小到大贪心,结果就Wa了,很容易找到反例:1 2 3 4 4 4 5 5 5

  如果从小到大贪,那么答案为1,不过这组数据眼睛看看答案都应该是3。造成这种情况的原因是我把数量少的先贪掉了,很多数量多的没得贪。因此贪心策略应该先贪数量多的。

代码如下:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 #define rep(i,n) for (int i = 0; i < (n); ++i)
  5 #define For(i,s,t) for (int i = (s); i <= (t); ++i)
  6 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
  7 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
  8 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
  9
 10 #define pr(x) cout << #x << " = " << x << "  "
 11 #define prln(x) cout << #x << " = " << x << endl
 12
 13 #define LOWBIT(x) ((x)&(-x))
 14
 15 #define ALL(x) x.begin(),x.end()
 16 #define INS(x) inserter(x,x.begin())
 17
 18 #define ms0(a) memset(a,0,sizeof(a))
 19 #define msI(a) memset(a,inf,sizeof(a))
 20 #define msM(a) memset(a,-1,sizeof(a))
 21
 22 #define pii pair<int,int>
 23 #define piii pair<pair<int,int>,int>
 24 #define mp make_pair
 25 #define pb push_back
 26 #define fi first
 27 #define se second
 28
 29 inline int gc(){
 30     static const int BUF = 1e7;
 31     static char buf[BUF], *bg = buf + BUF, *ed = bg;
 32
 33     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
 34     return *bg++;
 35 }
 36
 37 inline int ri(){
 38     int x = 0, f = 1, c = gc();
 39     for(; c<48||c>57; f = c==‘-‘?-1:f, c=gc());
 40     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
 41     return x*f;
 42 }
 43
 44 typedef long long LL;
 45 typedef unsigned long long uLL;
 46 const int inf = 1e9 + 9;
 47 const LL mod = 1e9 + 7;
 48 const int maxN = 1e5 + 7;
 49
 50 struct Node{
 51     int value, amount = 0;
 52
 53     inline bool operator < (const Node &x) const {
 54         return amount < x.amount;
 55     }
 56 };
 57
 58 int n, nlen, ans;
 59 Node nodes[maxN];
 60 unordered_map< int, int > mii;
 61 priority_queue< Node > maxH;
 62 int Ans[maxN][3];
 63
 64 int main(){
 65     while(cin >> n) {
 66         mii.clear();
 67         nlen = 0;
 68         rep(i, n) {
 69             int t;
 70             scanf("%d", &t);
 71             if(mii.find(t) != mii.end()) {
 72                 ++nodes[mii[t]].amount;
 73             }
 74             else {
 75                 mii[t] = nlen;
 76                 nodes[nlen].value = t;
 77                 nodes[nlen++].amount = 1;
 78             }
 79         }
 80
 81         while(!maxH.empty()) maxH.pop();
 82         rep(i, nlen) maxH.push(nodes[i]);
 83
 84         ans = 0;
 85
 86         while(maxH.size() >= 3) {
 87             Node a = maxH.top();
 88             maxH.pop();
 89             Node b = maxH.top();
 90             maxH.pop();
 91             Node c = maxH.top();
 92             maxH.pop();
 93
 94             int x = min(min(a.value, b.value), c.value);
 95             int z = max(max(a.value, b.value), c.value);
 96             int y = a.value + b.value + c.value - x - z;
 97             Ans[ans][0] = x;
 98             Ans[ans][1] = y;
 99             Ans[ans++][2] = z;
100
101             if(--a.amount) maxH.push(a);
102             if(--b.amount) maxH.push(b);
103             if(--c.amount) maxH.push(c);
104         }
105         cout << ans << endl;
106
107         rep(i, ans) printf("%d %d %d\n", Ans[i][2], Ans[i][1], Ans[i][0]);
108     }
109     return 0;
110 }

原文地址:https://www.cnblogs.com/zaq19970105/p/10752658.html

时间: 2024-10-10 00:06:10

CodeForces 140C New Year Snowm的相关文章

CodeForces 140C New Year Snowmen(堆)

题面 CodeForces 题解 因为要保证两两不同,所以不能单纯的开堆来维护,堆维护一个二元组,个数为第一关键字,编号为第二关键字,对于一个相同的颜色,统计一下这个颜色的个数再用堆来维护就好了. #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using std::min; using std::max; using std::sort; using st

CodeForces 140C - New Year Snowmen(数据结构)

题目链接:click here~~ [题目大意]给你一个整数序列,求最多选出每个长度为3的且序列元素单调的子序列的个数,并且输出每个子序列的元素,作为一个子序列,每个元素只能选一次,也就是满足一次性,但每个子序列里可以存在相同的元素, [解题思路]刚开始以为比较简单,就顺着思路写了一遍,第一发W了之后发现此题还是有一定的思维性,之后一直纠结在最多能选出多少子序列,因为考虑到如果序列里相同的元素的个数对最后结果会产生不同的影响,于是就想到了set容器的自动去重. 思想: 1,在判断set.size

New Year Snowmen 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 wit

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多

Codeforces 124A - The number of positions

题目链接:http://codeforces.com/problemset/problem/124/A Petr stands in line of n people, but he doesn't know exactly which position he occupies. He can say that there are no less than a people standing in front of him and no more than b people standing b

Codeforces 841D Leha and another game about graph - 差分

Leha plays a computer game, where is on each level is given a connected graph with n vertices and m edges. Graph can contain multiple edges, but can not contain self loops. Each vertex has an integer di, which can be equal to 0, 1 or  - 1. To pass th

Codeforces Round #286 (Div. 1) A. Mr. Kitayuta, the Treasure Hunter DP

链接: http://codeforces.com/problemset/problem/506/A 题意: 给出30000个岛,有n个宝石分布在上面,第一步到d位置,每次走的距离与上一步的差距不大于1,问走完一路最多捡到多少块宝石. 题解: 容易想到DP,dp[i][j]表示到达 i 处,现在步长为 j 时最多收集到的财富,转移也不难,cnt[i]表示 i 处的财富. dp[i+step-1] = max(dp[i+step-1],dp[i][j]+cnt[i+step+1]) dp[i+st

Codeforces 772A Voltage Keepsake - 二分答案

You have n devices that you want to use simultaneously. The i-th device uses ai units of power per second. This usage is continuous. That is, in λ seconds, the device will use λ·ai units of power. The i-th device currently has bi units of power store

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp