题意大意:很多人想进少林寺,少林寺最开始只有一个和尚,每个人有有一个武力值,若这个人想进少林,必须和比他先进去的人比武并且武力值最接近他的比武,如果有相同的则选择武力值比他小的,问当他进去的时候要和哪个和尚比武。
思路:正常情况暴力,n=100000
n*n的操作肯定不行的,最少要优化到nlogn,联想到map,map里的数会自动排序,它是由红黑树实现的,能实现O(n)的排序(对第一关键字排序),
然后再由mp.lower_bound(val)实现logn的查找。
总算法复杂度 n*logn
lower_bound()总结:
当参数 key 没有在容器 key的范围内:
1. 小于容器key uper_bound, lower_bound 都将返回 begin.
2. 大于容器key uper_bound, lower_bound 都将返回 end(注意end已经超界了)
当参数key 在容器key 范围内:
1. 参数 key == 容器key. lower_bound 将返回当前key 的iterator, uper_bound 将返回下一个元素的iterator.
2. 参数 key 不等于容器key,且在范围内, lower_bound将返回比参数key 大的且相邻的容器key的iterator
3 如果 Key等于 begin 或等于 end,将返回begin 或end
还有这题如果用cin和cout会超时。。。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <map>
#include <algorithm>
using namespace std;
int main()
{
int n;
while(scanf("%d",&n)!= EOF && n)
{
map<int,int> mp;
mp[1e9] = 1;
while(n--)
{
int k,g;
scanf("%d%d",&k,&g);
map<int,int>::iterator i = mp.lower_bound(g);
if(i == mp.begin()) printf("%d %d\n",k,i->second);
else
{
map<int,int>::iterator a = i, b= --i;
if((a->first - g) >= (g -b->first) )
{
printf("%d %d\n",k,b->second);
}
else printf("%d %d\n",k,a->second);
}
mp[g] = k;
}
}
return 0;
}