码迷,mamicode.com
首页 > 其他好文 > 详细

CF749D Leaving Auction

时间:2016-12-24 01:39:07      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:dex   printf   for   最小值   turn   problem   ios   main   ase   

题目链接:

http://codeforces.com/problemset/problem/749/D

题目大意:

一场拍卖会,共n个买家。这些买家共出价n次,有的买家可能一次都没有出价。每次出价用(ai,bi)表示,ai为此次出价人的编号,bi为价格。出价严格递增(bi<bi+1)并且没有玩家在一轮竞拍中在没有其他竞争对手的情况下自动增加自己的出价(ai!=ai+1)。现在给定q次查询,每次去掉一些出价者及其所有出价,问最后谁是赢家并且他以什么价格赢得拍卖品。

解题思路:

首先预处理所有的出价,保存每个买家的出价序列,最高出价和最低出价。然后维护一个set。其中保存出价者id和他的出价序列中的最高出价maxn,整个set按照maxn从大到小的顺序排序。对于每次查询,从set中删掉出局的人,如果此时set大小为0,输出“0 0”;大小为1,则只有一个买家,他赢得了拍卖品且价格为他的所有出价中的最小值;否则找maxn最高的人和第二高的人。最终的价格应该是在maxn最高的人的出价序列中比maxn第二高的人的最高出价高一点点的值。考虑到是有序的,二分即可。之后不要忘了把之前剔除掉的人再insert回来。

开始时我在set的每个节点中保存了相应买家的出价序列,结果T了很多次,真是被自己蠢哭了......

代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <vector>
  4 #include <set>
  5 #include <algorithm>
  6 #include <cstring>
  7 using namespace std;
  8 const int INF = 0x3f3f3f3f;
  9 vector<int> G[200005];
 10 int n, a, b;
 11 int maxn[200005];
 12 int minn[200005];
 13 int d[200005];
 14 int max(int a, int b)
 15 {
 16     return a > b ? a : b;
 17 }
 18 int min(int a, int b)
 19 {
 20     return a < b ? a : b;
 21 }
 22 struct node
 23 {
 24     int index;
 25     int maxn;
 26 };
 27 struct cmp
 28 {
 29     bool operator ()(const node & a, const node & b)const
 30     {
 31         return a.maxn > b.maxn;
 32     }
 33 };
 34 int main()
 35 {
 36     cin >> n;
 37     memset(minn, 0x3f, sizeof(minn));
 38     for (int i = 0; i < n; i++)
 39     {
 40         scanf("%d %d", &a, &b);
 41         G[a].push_back(b);
 42         maxn[a] = max(maxn[a], b);
 43         minn[a] = min(minn[a], b);
 44     }
 45     set<node, cmp> s;
 46     for (int i = 1; i <= n; i++)
 47     {
 48         if (G[i].size())
 49         {
 50             node tmp;
 51             tmp.index = i;
 52             tmp.maxn = maxn[i];
 53             s.insert(tmp);
 54         }
 55     }
 56     int T, x;
 57     cin >> T;
 58     for (int i = 0; i < T; i++)
 59     {
 60         scanf("%d", &x);
 61         for (int j = 0; j < x; j++)
 62         {
 63             scanf("%d", &d[j]);
 64             node t;
 65             t.index = d[j];
 66             t.maxn = maxn[d[j]];
 67             s.erase(t);
 68         }
 69         if (s.size() == 0)
 70         {
 71             puts("0 0");
 72         }
 73         else if (s.size() == 1)
 74         {
 75             printf("%d %d\n", s.begin()->index, minn[s.begin()->index]);
 76         }
 77         else
 78         {
 79             set<node, cmp>::iterator t = s.begin();
 80             node y;
 81             y.index = t->index;
 82             y.maxn = t->maxn;
 83             s.erase(s.begin());
 84             set<node, cmp>::iterator t2 = s.begin();
 85             vector<int>::iterator it;
 86             it = upper_bound(G[t->index].begin(), G[t->index].end(), t2->maxn);
 87             if (it != G[t->index].end())
 88             {
 89                 printf("%d %d\n", y.index, *it);
 90             }
 91             else
 92             {
 93                 puts("0 0");
 94             }
 95             s.insert(y);
 96         }
 97         for (int j = 0; j < x; j++)
 98         {
 99             node t;
100             t.index = d[j];
101             t.maxn = maxn[d[j]];
102             if (G[t.index].size())
103                 s.insert(t);
104         }
105     }
106     return 0;
107 }

 

CF749D Leaving Auction

标签:dex   printf   for   最小值   turn   problem   ios   main   ase   

原文地址:http://www.cnblogs.com/wangyiming/p/6216285.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!