zoukankan      html  css  js  c++  java
  • hdu 6695 Welcome Party 枚举 set

    把所有人按照sing从大到小排序,然后枚举sing值最高的人i,比他高的必须得去talk,维护必须去talk的这波人的最大值,作为maxn。

    然后两个情况,如果maxn>=sing[i],那么i作为sing最高的人情况下,显然talk中的最大值不可能小于maxn,我们再怎么往talk组加人,也只可能会让差距变大,所以把maxn - sing[i]和答案取min。

    如果maxn < sing[i],我们就去找i+1到n,这些人中,talk最接近sing[i]的两个人,一个大于等于sing[i],一个小于等于sing[i],用set中lower_bound实现,对于小于情况加入负数即可。注意这两个人必须都得大于maxn,才有意义。然后继续取min。

    maxn初值必须得是负无穷,要不然,第一个人的sing可能跟初值为0的maxn取出一个不存在的情况。被这个边界卡了一下午....

     1 #include <cstdio>
     2 #include <set>
     3 #include <algorithm>
     4 using namespace std;
     5 typedef long long ll;
     6 struct peo
     7 {
     8     ll sing,talk;
     9     friend bool operator < (peo a,peo b)
    10     {
    11         return a.sing > b.sing;
    12     }
    13 };
    14 multiset <ll> st[2];
    15 ll maxn,res;
    16 int T,n;
    17 peo vec[100100];
    18 int main()
    19 {
    20     for (scanf("%d",&T);T != 0;T--)
    21     {
    22         st[0].clear();
    23         st[1].clear();
    24         maxn = -10000000000;
    25         res = 1000000000000000000;
    26         scanf("%d",&n);
    27         for (int i = 1;i <= n;i++)
    28             scanf("%lld%lld",&vec[i].sing,&vec[i].talk);
    29         sort(vec + 1,vec + n + 1); 
    30         for (int i = 1;i <= n;i++)
    31         {
    32             st[0].insert(-vec[i].talk);
    33             st[1].insert(vec[i].talk); 
    34         }
    35         for (int i = 1;i <= n;i++)
    36         {
    37             st[0].erase(st[0].find(-vec[i].talk));
    38             st[1].erase(st[1].find(vec[i].talk));
    39             if (vec[i].sing <= maxn)
    40             {
    41                 res = min(maxn - vec[i].sing,res);
    42             }else 
    43             {
    44                 res = min(vec[i].sing - maxn,res);
    45                 if (st[0].lower_bound(-vec[i].sing) != st[0].end())
    46                 {
    47                     if (-*st[0].lower_bound(-vec[i].sing) >= maxn)
    48                         res = min(vec[i].sing + *st[0].lower_bound(-vec[i].sing),res);    
    49                 }
    50                 if (st[1].lower_bound(vec[i].sing) != st[1].end())
    51                 {
    52                     res = min(*st[1].lower_bound(vec[i].sing) - vec[i].sing,res);
    53                 }
    54             }
    55             maxn = max(vec[i].talk,maxn);
    56         }
    57         printf("%lld
    ",res);
    58     }
    59     return 0;
    60 }
    心之所动 且就随缘去吧
  • 相关阅读:
    WCF学习笔记1发布使用配置文件的服务
    Oracle(Hierarchical Queries)层级查询
    Telerik UI For WinForms关于RadGridView的列排序
    C#异步显示工作进度
    CodeSmith连接Oracle
    Access数据导入SQLServer2008R2
    Oracle (RANK) 排名函数
    C#INotifyPropertyChanged(解决数据绑定的界面刷新问题)
    Code Complete读书笔记03
    C++ Primer Plus读书笔记08
  • 原文地址:https://www.cnblogs.com/iat14/p/11421969.html
Copyright © 2011-2022 走看看