hdu 4585 Shaolin 2013 ACM-ICPC杭州赛区全国邀请赛——题目重现

实际上要做题目就是要进行快速的查找和插入,这个功能可以用set来实现

所代码就很好写了

/*********
PRO: hdu 4585
TIT: Shaolin
DAT: 2013-08-10-12.28
AUT: UKean
EMA: [email protected]
*********/
#include<cstdio>
#include<algorithm>
#include<set>
#define INF 1e18
using namespace std;
int n;
struct monk
{
    int id,grade;
    bool operator <(const monk& b)const//递增排序
    {
        return grade<b.grade;
    }
};
typedef set<monk>::iterator SetIt;

set<monk> se;
inline int fabs(int x){return x>0?x:-x;}
monk choose(monk a,monk now,monk b)//如果有2个可能的选择的话,怎样去选的子函数
{
    int aa=fabs(a.grade-now.grade);
    int bb=fabs(now.grade-b.grade);
    if(aa>bb) return b;
    if(aa<bb) return a;
    if(a.grade<now.grade)
        return a;
    return b;
}
void deal()
{
    se.clear();
    monk now,ans;
    now.id=1;now.grade=100000000;
    se.insert(now);//插入第一个点
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&now.id,&now.grade);
        SetIt it=se.lower_bound(now),left;//二分查找,找到的是大于等于now.grade的和尚
        if(it!=se.begin())//如果找到的不是最小的,那么可能有2个选择的可能,另外因为新来的不可能是最大的
        {
             left=it;left--;
             ans=choose(*left,now,*it);
         }
        else  ans=*it;//找到的是最小的的时候,就可以确定答案了
        printf("%d %d\n",now.id,ans.id);
        se.insert(now);// 插入
    }
}
int main()
{
    while(scanf("%d",&n),n) deal();
    return 0;
}


你可能感兴趣的:(HDU,2013,ACM-ICPC杭州赛区全国邀,4585,Shaolin)