cf555b
2015-07-14 23:26
417 查看
题意:按顺序给出多个互不相交的区间(表示一些小岛),和一些可以连接区间的桥,每个桥有固定的长度。区间和桥的数量都是2*10^5。
两个相邻的小岛之间的桥的长度必须小于等于最远点距离,大于等于最近点距离。问是否能用这些桥把所有小岛连接在一起。
分析:区间排序问题。但是这个题里需要排序的区间并不是题里直接给出的小岛。而是要先把桥从小到大排序。
然后对于每两个相邻小岛,在这个桥的序列里都有一个区间内的桥是可以用来连接这两个小岛的。
对于每两个相邻小岛,求出其对应的桥区间,然后把这些区间排序。
排序规则是先按右边缘从小到大,右边相同的按左边缘从小到大。
排序后依次在这些区间里选取对应的桥,每次选取区间内最小的未被使用的桥即可。
至于排序的时候为什么先又后左,是因为不同区间对于左侧的桥资源的迫切程度,肯定是右边缘越偏左,需求越迫切。
所以应当优先将左侧的资源分配给右边缘比较偏左的区间。
要求一个数字集合里面位于一个区间内的最小值,可以用lower_bound函数。
而依次删除使用过的桥,可以用multiset(它有lower_bound这个成员函数)。
当想要使用包含三个值的结构体的时候,可以用两个pair嵌套。
View Code
两个相邻的小岛之间的桥的长度必须小于等于最远点距离,大于等于最近点距离。问是否能用这些桥把所有小岛连接在一起。
分析:区间排序问题。但是这个题里需要排序的区间并不是题里直接给出的小岛。而是要先把桥从小到大排序。
然后对于每两个相邻小岛,在这个桥的序列里都有一个区间内的桥是可以用来连接这两个小岛的。
对于每两个相邻小岛,求出其对应的桥区间,然后把这些区间排序。
排序规则是先按右边缘从小到大,右边相同的按左边缘从小到大。
排序后依次在这些区间里选取对应的桥,每次选取区间内最小的未被使用的桥即可。
至于排序的时候为什么先又后左,是因为不同区间对于左侧的桥资源的迫切程度,肯定是右边缘越偏左,需求越迫切。
所以应当优先将左侧的资源分配给右边缘比较偏左的区间。
要求一个数字集合里面位于一个区间内的最小值,可以用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 = 2 * (int)(1e5) + 10; 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 = 0; i < island_num - 1; i++) { long long l = range[i].second.first; long long r = range[i].first; __typeof(bridge.begin()) it = bridge.lower_bound(make_pair(l, -1)); 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 = 0; i < island_num; i++) { long long a, b; cin >> a >> b; island[i] = make_pair(a, b); } for (int i = 0; i < bridge_num; i++) { long long a; cin >> a; bridge.insert(make_pair(a, i)); } } int main() { input(); for (int i = 0; i < island_num - 1; i++) { long long min_len = island[i + 1].first - island[i].second; long long max_len = island[i + 1].second - island[i].first; range[i] = make_pair(max_len, make_pair(min_len, i)); } sort(range, range + island_num - 1); if (ok()) { puts("Yes"); for (int i = 0; i < island_num - 1; i++) { if (i != 0) putchar(' '); printf("%d", ans[i] + 1); } putchar('\n'); } else puts("No"); return 0; }
View Code
相关文章推荐
- HDU 1166 解题报告 线段树
- 开篇:什么是算法
- hdu 1024 dp
- 光流法学习(1)-找Demo
- iPhone 6plus一卡双号
- 前路漫漫
- Lua5.2.3源码阅读(3)-Table(ipairs,pairs)
- 送H-1B 及其他I-129 申请别忘用新表
- 张珺 2015/07/14 个人文档
- ios学习笔记-05-渐变动画和button布局和kvc-kvo
- I-129表
- Android Proguard 代码混淆总结
- 【独立开发者er Cocos2d-x实战 008】BMFont生成位图字体工具和Cocos2dx使用加载fnt文件
- iOS面试之oc
- String to Integer (atoi)
- 探测法的哈希表的C++实现(最新修改)
- mysql分布式数据库原理以及实践
- Python标准库05 存储对象 (pickle包,cPickle包)
- 欢迎使用CSDN-markdown编辑器
- 任笑萱 2015/7/14 个人文档