题意:按顺序给出多个互不相交的区间(表示一些小岛),和一些可以连接区间的桥,每个桥有固定的长度。区间和桥的数量都是2*10^5。

两个相邻的小岛之间的桥的长度必须小于等于最远点距离,大于等于最近点距离。问是否能用这些桥把所有小岛连接在一起。

分析:区间排序问题。但是这个题里需要排序的区间并不是题里直接给出的小岛。而是要先把桥从小到大排序。

然后对于每两个相邻小岛,在这个桥的序列里都有一个区间内的桥是可以用来连接这两个小岛的。

对于每两个相邻小岛,求出其对应的桥区间,然后把这些区间排序。

排序规则是先按右边缘从小到大,右边相同的按左边缘从小到大。

排序后依次在这些区间里选取对应的桥,每次选取区间内最小的未被使用的桥即可。

至于排序的时候为什么先又后左,是因为不同区间对于左侧的桥资源的迫切程度,肯定是右边缘越偏左,需求越迫切。

所以应当优先将左侧的资源分配给右边缘比较偏左的区间。

要求一个数字集合里面位于一个区间内的最小值,可以用lower_bound函数。

而依次删除使用过的桥,可以用multiset(它有lower_bound这个成员函数)。

当想要使用包含三个值的结构体的时候,可以用两个pair嵌套。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
using namespace std; #define d(x) const int MAX_N = * (int)(1e5) + ; pair<long long, long long> island[MAX_N];
int bridge_num;
int island_num;
int ans[MAX_N];
pair<long long, pair<long long, int> > range[MAX_N];
multiset<pair<long long, int> > bridge; bool ok()
{
for (int i = ; i < island_num - ; i++)
{
long long l = range[i].second.first;
long long r = range[i].first;
__typeof(bridge.begin()) it = bridge.lower_bound(make_pair(l, -));
if (it == bridge.end())
return false;
if ((*it).first > r)
return false;
ans[range[i].second.second] = it->second;
bridge.erase(it);
}
return true;
} void input()
{
scanf("%d%d", &island_num, &bridge_num);
for (int i = ; i < island_num; i++)
{
long long a, b;
cin >> a >> b;
island[i] = make_pair(a, b);
}
for (int i = ; i < bridge_num; i++)
{
long long a;
cin >> a;
bridge.insert(make_pair(a, i));
}
} int main()
{
input(); for (int i = ; i < island_num - ; i++)
{
long long min_len = island[i + ].first - island[i].second;
long long max_len = island[i + ].second - island[i].first;
range[i] = make_pair(max_len, make_pair(min_len, i));
} sort(range, range + island_num - ); if (ok())
{
puts("Yes");
for (int i = ; i < island_num - ; i++)
{
if (i != )
putchar(' ');
printf("%d", ans[i] + );
}
putchar('\n');
}
else
puts("No");
return ;
}

cf555b的更多相关文章

  1. CF555B 贪心

    http://codeforces.com/problemset/problem/555/B B. Case of Fugitive time limit per test 3 seconds mem ...

  2. CF555B Case of Fugitive

    题目大意 有一些不相交线段和一些桥,桥可以架在两个相邻的线段上.求现有的桥是否可以使所有线段连通. 题解 在两个线段上架桥,桥的长度在一个范围内,相当于一个长度的区间,一个桥只有一个长度,相当于一个长 ...

随机推荐

  1. Winform端上传图片到服务器

    转载自  在winform实现文件上传到服务器 webform上传文件可能大家都写过很多,一个HtmlInputFile.PostedFile.SaveAs就搞定了,不过不知道大家有没有在winfor ...

  2. linux安装-版本选择-终极决定

    选用64位或32位的版本,注意看硬件: 内存大于4G的用64位, 小于4G的用32位 同时, 64位的版本在软件源, 软件的兼容性等问题. ----------------------------- ...

  3. 如何在linux环境下安装yaf

    我本机的环境配置 linuxMint17.1 php5.5 nginx1.4.6 下面开始安装 下载最新的yaf包 http://pecl.php.net/package/yaf 我下载的最新版本为2 ...

  4. CF448C Painting Fence (分治递归)

    Codeforces Round #256 (Div. 2) C C. Painting Fence time limit per test 1 second memory limit per tes ...

  5. STL删除元素

    1.从vector中删除多个元素: #include <iostream> #include <vector> int main() { std::vector<int& ...

  6. Junit初级编码(一)第一个Junit测试程序

    序,Junit测试是单元测试的一个框架,提供了很多方法,供我们快速开展单元测试.目前最新版本JAR包为4.12,官网地址为http://junit.org/ 一.第一个Junit测试程序 1 去官网下 ...

  7. UIGestureRecognizer

    •为了完成手势识别,必须借助于手势识别器----UIGestureRecognizer • •利用UIGestureRecognizer,能轻松识别用户在某个view上面做的一些常见手势 • •UIG ...

  8. Redis数据库的使用与介绍

    本周11-15号开始用Redis数据库在现有的平台基础上开发一个独立模块,这是一个边学习.边记录.边交流.边开发.边总结的过程.大部分随笔都是个人的“工作日志”,旨在记录自己学习过程中收集的一些资料, ...

  9. HDOJ 4336 Card Collector

    容斥原理+状压 Card Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  10. substr — 详解

    substr — 返回字符串的子串 举例说明: string substr ( string $string , int $start , int $length ) 返回字符串 string 由 s ...