zoukankan      html  css  js  c++  java
  • codeforces 555B Case of Fugitive

    题目连接:

      http://codeforces.com/problemset/problem/555/B

    题目大意:

      有n个岛屿(岛屿在一列上,可以看做是线性的,用来描述岛屿位置的是起点与终点),m个桥,给出每个岛屿的位置和桥的长度,问是否可以把n个岛屿连起来?

    解题思路: 

      排序+贪心,对于n个岛屿,相邻的两个之间起点和端点可以转化为n-1个连接桥的长度区间,把区间升序排列。

      对于m个桥升序排列,对于每一个桥枚举每个可以合法覆盖的区间,选取最优的,选取的时候满足L<bridge_length<R,L经是有序的了。我们只需选取R最小的那个,因为R越大,这个区间就能适应更多的桥。

      本宝宝对于选取最优区间的时候采用了优先队列,并不是最优的处理方式,大家有好的办法可以留言告诉弱弱。

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <cmath>
      7 #include <queue>
      8 using namespace std;
      9 
     10 const int maxn = 200010;
     11 #define LL __int64
     12 struct bridge
     13 {
     14     LL val, id;
     15     bool operator < (const bridge &a) const
     16     {
     17         return val < a.val;
     18     }
     19 } Bri[maxn];
     20 
     21 struct island
     22 {
     23     LL r, l, id;
     24     bool operator < (const island &a) const
     25     {
     26         return l < a.l;
     27     }
     28 } Is[maxn];
     29 struct node
     30 {
     31     LL s, id;
     32     bool operator < (const node &a) const
     33     {
     34         return s > a.s;
     35     }
     36 };
     37 
     38 LL vis[maxn], n, m;
     39 bool solve ()
     40 {
     41     priority_queue <node>Q;//当前桥可以搭建成功的区间
     42     int l=0;
     43     memset (vis, 0, sizeof(vis));
     44 
     45     for (int i=0; i<m; i++)//对于每个桥选取最优的区间搭建
     46     {
     47         node nu;
     48         while (!Q.empty())
     49         {
     50             nu = Q.top();
     51             if (nu.s < Bri[i].val)
     52                 Q.pop();//删除队列中的不合法区间
     53             else
     54                 break;
     55         }
     56 
     57         while (Bri[i].val>=Is[l].l && Is[l].r >= Bri[i].val && l<n-1)
     58         {
     59             nu.id = Is[l].id;
     60             nu.s = Is[l].r;
     61             Q.push (nu);//区间加进队列
     62             l ++;
     63         }
     64         if (Q.empty())
     65             continue;//没有合适的边,就继续循环加边
     66         nu = Q.top ();
     67         vis[nu.id] = Bri[i].id;//记录连接区间所对应的边
     68         Q.pop();
     69     }
     70     for (int i=1; i<n; i++)
     71         if (!vis[i])
     72             return false;
     73     return true;//所有区间都对应有边
     74 }
     75 int main ()
     76 {
     77     while (scanf ("%I64d %I64d", &n, &m) != EOF)
     78     {
     79         island pre, cur;
     80         LL i;
     81         scanf ("%I64d %I64d", &pre.l, &pre.r);
     82         for (i=1; i<n; i++)
     83         {
     84             scanf ("%I64d %I64d", &cur.l, &cur.r);
     85             Is[i-1].id = i;
     86             Is[i-1].l = cur.l - pre.r;
     87             Is[i-1].r = cur.r - pre.l;
     88             pre = cur;
     89         }
     90         for (i=0; i<m; i++)
     91         {
     92             Bri[i].id = i+1;
     93             scanf ("%I64d", &Bri[i].val);
     94         }
     95         sort (Is, Is+n-1);
     96         sort (Bri, Bri+m);
     97         if (solve ())
     98         {
     99             printf ("Yes
    ");
    100             for (i=1; i<n-1; i++)
    101                 printf ("%I64d ", vis[i]);
    102             printf ("%I64d
    ", vis[i]);
    103         }
    104         else
    105             printf ("No
    ");
    106     }
    107     return 0;
    108 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    HTML编辑器(1)
    HTML轮播(2)
    HTML轮播(1)
    MVC联想查询绑定下拉框
    Flex布局
    css垂直水平居中问题
    rem,em,px的区别
    css中的定位、清除浮动
    css3的盒模型
    HTML的语义化
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4606248.html
Copyright © 2011-2022 走看看