#include <iostream>
#include <map>
#include <algorithm>
#include <cstring>
using namespace std;
int main()
{
int n;
cin >> n;
int power, id;
map<int, int> mp;
map<int, int>::iterator p;
mp[1000000000] = 1;
while (n--)
{
cin >> id >> power;
p = mp.lower_bound(power); //查找第一个大于等于的值
if (p == mp.end()) //没有大于等于power的
p--;
int t = abs(p->first - power);
int ansID = p->second;
if (p != mp.begin()) //不用while,因为map容器里面没有实力值相等的
{
p--;
if (abs(p->first - power) < t || (abs(p->first - power) == t && p->second < ansID))
ansID = p->second;
}
cout << id << " " << ansID << endl;
p = mp.find(power); //在容器中查找实力值和power相等的,如果查找到了 就比较它们的id,将id小的放在里面。
if (p->second > id || p == mp.end())
mp[power] = id;
}
return 0;
}
这个题目其实是上一个题目的翻版(没有放出),改动主要在于,之前的题目要求任意两人的实力值不同,且最后输出时如果有两个人与这个人的实力差相同,则选择实力弱的那个(毕竟大家都喜欢虐人不喜欢被虐)。所以前一个题目我用的是set。
这个题目一开始想用multiset,因为看到了两人的实力值可以相同。但其实有一种更简单的方法,是使用map来做,键(first)为实力值,值(second)为id。这难道不是违反题目中两个人id可以相同的规定么?
其实不然,使用map完全是因为题设中输出的要求:如果最后有两个候选人(上面说的实力差相等),则输出id小的那个。既然这然,我们就可以在插入一个新的成员时,如果map中已经有人的实力值与新插入的这个相同,那就谁的id小就用谁的id,毕竟最后如果实力差相同了,也只会用到最小的那个id。也就是说,如果两个人的实力值相同的话,以后也就id小的那个人会用来比较(id大的那个人连成为工具人的机会都没有了),那就干脆不用存这个id大的人儿了呗!
当然,用实力值最为键是首先就要想到的,毕竟调用 lower_bound
这种函数的时候是要使用“<”运算符比较的