Leaving Auction CF 749D

时间:2022-09-20 23:17:38

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

题目大意:

有n个人竞拍,也有n个叫牌,一个人可以有多个叫价牌,但也可能有一些人根本不叫价

每个叫牌由叫价人的下标和价码,后叫的价码一定比前面的高,而且不会有人连续出两次价(即不与自己竞价)

可能会有一些人离场,如果下标为1的人离场了,那么他参与的叫价均作废。

如果因离场致使出现某人连续竞价的情况,那么,按此人连续竞价最早的价码计算。

问,在有人离场的情况下,输出那个人以什么样的价码赢得拍卖,均离场,则输出0 0

思路:

记录每个人出价最高的时候,从右往左遍历,如果该编号的人离场了,则跳过,直到找到第一个未离场的人,此人即为获胜者

然后算出正确出价:上面的步骤继续往下找,下一个没有离场的人,用此人的最高价到获胜者的出价序列中找到第一个大于(因为出价按时间递增)此价的价码即为答案

代码如下:

 #include<iostream>
#include<map>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std; const int MAX = 2e5 + ;
int Pos[MAX]; //每个人参与竞拍,出价最高的时候
long B[MAX]; //对应每个人出的最高价
map<int, bool>P;
vector<long> Prices[MAX]; //每个人的价位表 inline bool my_cmp(const int lhs, const int rhs)
{
return B[lhs] < B[rhs];
} int main()
{
int N, Q, K, l, result, a;
scanf("%d", &N);
for (long b = , i = ; i <= N && (Pos[i] = i); ++i, B[a] = b)
{
scanf("%d %ld", &a, &b);
Prices[a].push_back(b);
}
sort(Pos + , Pos + N + , my_cmp);
scanf("%d", &Q);
while (Q--)
{
P.clear(), result = ;
scanf("%d", &K);
while (K--)
{
scanf("%d", &l);
P[l] = true;
}
int i = ;
for (i = N; i > ; --i)
{
if (!P[Pos[i]])
{
if (result)break;
result = Pos[i];
}
}
if (result&&B[result])printf("%d %ld\n", result, *upper_bound(Prices[result].begin(), Prices[result].end(), B[Pos[i]]));
else printf("0 0\n");
}
return ;
}

感谢您的阅读,生活愉快~