//upper_bound Returns the first elment beyond the range
# include <iostream>
# include <cstdio>
# include <map>
# include <cmath>
using namespace std;
multimap<int,int> member;
int findMin(multimap<int,int>::iterator& start, multimap<int,int>::iterator& end) //找到区间中最小id
{
multimap<int,int>::iterator i;
int min = 1000000001;
for ( i = start; i != end; i++ )
{
if ( i->second < min )
{
min = i->second;
}
}
return min;
}
int findMinEXPT(multimap<int,int>::iterator& start, multimap<int,int>::iterator& end, int id) //找到除本身外的最小id
{
multimap<int,int>::iterator i;
int min = 1000000001;
for ( i = start; i != end; i++ )
{
if ( i->second < min && i->second != id )
{
min = i->second;
}
}
return min;
}
multimap<int,int>::iterator findPos(int p,int id)
{
multimap<int,int>::iterator i;
for ( i = member.lower_bound(p); i != member.upper_bound(p); i++ )
{
if ( i->second == id )
{
return i;
}
}
return member.end();
}
void match(int p,int id)
{
int matchID = 0;
int matchID_sub = 0;
int lower = 0;
int upper = 0;
multimap<int,int>::iterator i;
multimap<int,int>::iterator j;
multimap<int,int>::iterator k;
j = member.lower_bound(p);
k = member.upper_bound(p);
k--;
if ( j != member.end() && k != member.end() )
{
if ( j == k ) //There is only one element that has the power p
{
if ( j == member.begin() ) //插入元素是第一个,则只需寻找其后满足条件的答案
{
i = j;
k++;
j++;
k = member.upper_bound(k->first);
matchID = findMin(j,k);
printf("%d %d\n",i->second,matchID);
}
else //插入元素不是第一个,则需要两头寻找
{
i = j;
j--;
k++;
lower = i->first - j->first;
upper = k->first - i->first;
if ( lower < upper ) //如果左邻实力更接近,则寻找左邻中id最小的
{
j = member.lower_bound(j->first);
matchID = findMin(j,i);
printf("%d %d\n",i->second,matchID);
}
else if ( lower > upper )
{
j++;
j++;
k = member.upper_bound(k->first);
matchID = findMin(j,k);
printf("%d %d\n",i->second,matchID);
}
else //如果两遍实力相差一样,那么就在两个区间的并集中寻找id最小的
{
int currentID = i->second;
int downRange = j->first;
int upRange = k->first;
j = member.lower_bound(downRange);
k = member.upper_bound(upRange);
matchID = findMin(j,i);
j = i;
j++;
matchID_sub = findMin(j,k);
int finalMatch = min(matchID,matchID_sub);
printf("%d %d\n",currentID,finalMatch);
}
}
}
else //如果有多个选手实力与新手相等,那么在这些人中找id最小的即可
{
k++;
i = findPos(p,id);
matchID = findMinEXPT(j,k,i->second);
printf("%d %d\n",i->second,matchID);
}
}
else return;
}
int main()
{
int n = 0;
int id = 0;
int power = 0;
cin >> n;
member.insert(make_pair(1000000000,1));
for ( int i = 0; i < n; i++ )
{
scanf("%d%d",&id,&power);
member.insert(make_pair(power,id));
match(power,id);
}
return 0;
}
OPENJUDGE 冷血格斗场
最新推荐文章于 2024-07-10 12:29:01 发布