hdu 4585 Shaolin_set用法

题目链接

题意:有n个人想成为少林,但是成为少林必须跟少林的大师大一场,当然要选择战斗力很近的,有两大师战斗力跟那人相近程度一样就选战斗力小的那个,按输入顺序,先输入的人先成为少林大师,后面输入的人,选一个前面输入的人打一场,当然少林已经存在一个超级大师(初始号码为1,不用输入已存在)。

思路:我开头用排序搞来搞去都没成,后来看看人题解,瞬间发觉set很好用,像优先队列一样自己会排好序了。

函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置


举例如下:


一个数组number序列为:4,10,11,30,69,70,96,100.设要插入数字3,9,111.pos为要插入的位置的下标则


pos = lower_bound( number, number + 8, 3) ,pos = 0.即number数组的下标为0的位置。


pos = lower_bound( number, number + 8, 9) , pos = 1,即number数组的下标为1的位置(即10所在的位置)。


pos = lower_bound( number, number + 8, 111), pos = 8,即number数组的下标为8的位置(但下标上限为7,所以返回最后一个元素的下一个元素)。


所以,要记住:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,


且last的位置是越界的!!~


返回查找元素的第一个可安插位置,也就是“元素值>=查找值”的第一个元素的位置

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<map>
using namespace std;

int main(){
    int n,k,g;
    set<int> st;
    map<int,int> mp;
    while(~scanf("%d",&n) && n){
        st.clear();
        mp.clear();
        st.insert(1000000000);
        mp[1000000000]=1;
        while(n--){
            scanf("%d%d",&k,&g);
            printf("%d ",k);
            set<int>::iterator it=st.lower_bound(g);
            int tmp=(*it);
            if(it!=st.begin()){
                it--;//比他战斗力少的第一个
                if((*it)-g>=g-tmp)
                   printf("%d\n",mp[(*it)]);
                else
                   printf("%d\n",mp[tmp]);
            }else
                printf("%d\n",mp[(*it)]);
            
            mp[g]=k;
            st.insert(g);
        }
    }
    return 0;
}



posted @ 2014-04-15 14:56  Teemo的技术blog  阅读(195)  评论(0编辑  收藏  举报