HRBUST - 2069-萌萌哒十五酱的衣服~-multiset-lower_bound

众所周知,十五酱有很多的衣服,而且十五酱东西收拾的非常糟糕。

    所以十五酱经常找不到合适的衣服穿,于是她觉得收拾一下屋子,把衣服配成一套一套的~(即一件衬衫一件裤子。

    十五酱一共有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配对,这个问题终于在今天想通了-_-|||...

还有些要注意的地方就写进代码注释里了...

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<set>
 5 #include<algorithm>
 6 using namespace std;
 7 const int amn=1e3+5;
 8 const int mod=1e6;
 9 int f=-1;
10 multiset<int>m;
11 int main()
12 {
13     int n,a,b;
14     while(cin>>n)
15     {
16         int sum=0;
17         for(int t=1;t<=n;t++)
18         {
19             cin>>a>>b;
20             if(f==-1)
21             {
22                 f=a;
23                 m.insert(b);
24             }
25             else if(a==f)
26             {
27                 m.insert(b);
28             }
29             else
30             {
31                 ///为什么要2个迭代器?
32                 ///1.可能会有没查到小于等于b的数,那么就需要返回上一个元素。
33                 ///2.可能会有现在这件物品与属性值更大的另一种物品算出来的值比属性值相对更小的另一种物品要小
34                 multiset<int>::iterator it1;
35                 multiset<int>::iterator it2;
36                 it1=m.lower_bound(b);
37                 it2=it1;
38                 it1--;
39                 if(it2==m.begin())
40                 {
41                     sum=sum%mod+abs(b-*it2);
42                     m.erase(it2);
43                 }
44                 else if(it2==m.end())///如果迭代器查到m.end(),就是没查到小于等于b的数,那么就需要返回上一个元素。
45                 {
46                     sum=sum%mod+abs(b-*it1);
47                     m.erase(it1);
48                 }
49                 else
50                 {
51                     ///如果属性差值一样,那么十五就会选择属性值较小的一个
52                     if(abs(b-*it2)<abs(b-*it1))
53                     {
54                         sum=sum%mod+abs(b-*it2);m.erase(it2);
55                     }
56                     else  ///其实这里相当于if(abs(b-*it1)<=abs(b-*it2))
57                     {
58                         sum=sum%mod+abs(b-*it1);m.erase(it1);
59                     }
60                 }
61             }
62             if(m.empty())
63             {
64                 f=-1;
65             }
66         }
67         cout<<sum%mod<<endl;
68     }
69 }

 

转载于:https://www.cnblogs.com/Railgun000/p/10610792.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值