题目:http://codeforces.com/problemset/problem/749/D
题目大意:
有n个人竞拍,也有n个叫牌,一个人可以有多个叫价牌,但也可能有一些人根本不叫价
每个叫牌由叫价人的下标和价码,后叫的价码一定比前面的高,而且不会有人连续出两次价(即不与自己竞价)
可能会有一些人离场,如果下标为1的人离场了,那么他参与的叫价均作废。
如果因离场致使出现某人连续竞价的情况,那么,按此人连续竞价最早的价码计算。
问,在有人离场的情况下,输出那个人以什么样的价码赢得拍卖,均离场,则输出0 0
思路:
记录每个人出价最高的时候,从右往左遍历,如果该编号的人离场了,则跳过,直到找到第一个未离场的人,此人即为获胜者
然后算出正确出价:上面的步骤继续往下找,下一个没有离场的人,用此人的最高价到获胜者的出价序列中找到第一个大于(因为出价按时间递增)此价的价码即为答案
代码如下:
1 #include<iostream> 2 #include<map> 3 #include<cstdio> 4 #include<vector> 5 #include<algorithm> 6 using namespace std; 7 8 const int MAX = 2e5 + 10; 9 int Pos[MAX]; //每个人参与竞拍,出价最高的时候 10 long B[MAX]; //对应每个人出的最高价 11 map<int, bool>P; 12 vector<long> Prices[MAX]; //每个人的价位表 13 14 inline bool my_cmp(const int lhs, const int rhs) 15 { 16 return B[lhs] < B[rhs]; 17 } 18 19 int main() 20 { 21 int N, Q, K, l, result, a; 22 scanf("%d", &N); 23 for (long b = 0, i = 1; i <= N && (Pos[i] = i); ++i, B[a] = b) 24 { 25 scanf("%d %ld", &a, &b); 26 Prices[a].push_back(b); 27 } 28 sort(Pos + 1, Pos + N + 1, my_cmp); 29 scanf("%d", &Q); 30 while (Q--) 31 { 32 P.clear(), result = 0; 33 scanf("%d", &K); 34 while (K--) 35 { 36 scanf("%d", &l); 37 P[l] = true; 38 } 39 int i = 0; 40 for (i = N; i > 0; --i) 41 { 42 if (!P[Pos[i]]) 43 { 44 if (result)break; 45 result = Pos[i]; 46 } 47 } 48 if (result&&B[result])printf("%d %ld\n", result, *upper_bound(Prices[result].begin(), Prices[result].end(), B[Pos[i]])); 49 else printf("0 0\n"); 50 } 51 return 0; 52 }
感谢您的阅读,生活愉快~