
#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 这种函数的时候是要使用“<”运算符比较的
