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; }