众所周知,十五酱有很多的衣服,而且十五酱东西收拾的非常糟糕。
所以十五酱经常找不到合适的衣服穿,于是她觉得收拾一下屋子,把衣服配成一套一套的~(即一件衬衫一件裤子。
十五酱一共有n件衣服,有衬衫有裤子,每一件衣服都有自己的属性值a(a是一个正整数,a<2^31)
十五酱每次手上只能拿一类衣服(如全是裤子,或全是衬衫
如果十五手上都是衬衫,那么当她拿到的下一件衣服是属性值为b的裤子时,她就会从手中的衬衫中找到属性值与这条裤子最接近的搭配成一套丢进衣柜中,如果有两件衣服和裤子的属性差值一样,那么十五就会选择属性值较小的一个衬衫。
如果十五手上的都是裤子,那么当她拿到的下一件衣服是属性值为b的衬衫时,她就会从手中的裤子中找到属性值与这条衬衫最接近的搭配成一套丢进衣柜中,如果有两件裤子和衣服的属性差值一样,那么十五就会选择属性值较小的一个裤子。
当然这样就会产生属性差了。。。。(即abs(a-b))
十五想知道她这样搭配衣服最终产生的属性差是多少
Input
多组数据
一行为一个正整数n(n<=80000)如题意;
接下来的n行,按到来时间的先后顺序描述了十五拿衣服种类和属性值
每行有两个正整数a, b,其中a=0表示衬衫,a=1表示裤子,b表示衬衫的特点值或是裤子的特点值。(同一时间内十五手上的衣服不会超过10000个)
Output
多组数据
每组数据输出一个正整数,表示十五搭配完全部衣服后的衣服属性差的总和mod 1000000以后的结果。
Sample Input5
0 2
0 4
1 3
1 2
1 5
Sample Output3Hint
(abs(3-2) + abs(2-4)=3,最后一个裤子没有衣服可以配~)
十五酱最萌了昂~
过了一个学期,决定来挑战一下以前没写出来的STL题
然而我的知识储备不足,所以借鉴(copy)了
Bryant~xw大佬的代码
原文链接:https://www.cnblogs.com/hhkobeww/p/7684754.html
multiset可加入可重复的元素,并用lower_bound查找第一个不大于b的数。
如果迭代器查到m.begin(),就算第一个就行了,但如果迭代器查到m.end(),就是没查到小于等于b的数,那么就需要返回上一个元素。
如果迭代器查到的是中间的元素,那么就用当前查到的元素计算后和上一个查到的元素计算后比大小,这里要先处理较小的元素,因为题目中这样描述,如果属性差值一样,那么十五就会选择属性值较小的一个,比如说这个样例,3查到4,4上一个元素是2,abs(3-4)==abs(3-2)==1,但2<4,所以先与2配对,这个问题终于在今天想通了-_-|||...
还有些要注意的地方就写进代码注释里了...
#include<iostream> #include<cstdio> #include<cstring> #include<set> #include<algorithm> using namespace std; ; const int mod=1e6; ; multiset<int>m; int main() { int n,a,b; while(cin>>n) { ; ;t<=n;t++) { cin>>a>>b; ) { f=a; m.insert(b); } else if(a==f) { m.insert(b); } else { ///为什么要2个迭代器? ///1.可能会有没查到小于等于b的数,那么就需要返回上一个元素。 ///2.可能会有现在这件物品与属性值更大的另一种物品算出来的值比属性值相对更小的另一种物品要小 multiset<int>::iterator it1; multiset<int>::iterator it2; it1=m.lower_bound(b); it2=it1; it1--; if(it2==m.begin()) { sum=sum%mod+abs(b-*it2); m.erase(it2); } else if(it2==m.end())///如果迭代器查到m.end(),就是没查到小于等于b的数,那么就需要返回上一个元素。 { sum=sum%mod+abs(b-*it1); m.erase(it1); } else { ///如果属性差值一样,那么十五就会选择属性值较小的一个 if(abs(b-*it2)<abs(b-*it1)) { sum=sum%mod+abs(b-*it2);m.erase(it2); } else ///其实这里相当于if(abs(b-*it1)<=abs(b-*it2)) { sum=sum%mod+abs(b-*it1);m.erase(it1); } } } if(m.empty()) { f=-; } } cout<<sum%mod<<endl; } }