NYOJ 12 喷水装置(二)
来源:互联网 发布:淘宝联盟21号不能提现 编辑:程序博客网 时间:2024/06/04 23:28
此题应转化为区间覆盖问题,数轴上有 n 个闭区间 [ai, bi],选尽量少的区间覆盖一条指定线段 [s, t]。
将区间按 b 从小到大排序,用 sum 记录当前在线段上覆盖到的位置,每次对整个闭区间扫描,
扫描结果:
1. 线段上有的区间覆盖不到,则无法完成覆盖,跳出扫描循环;
2. 选择能覆盖到 sum 位置且最长的闭区间,用它来覆盖,贪心,保证选的区间少,sum += q[i].b - sum。
代码如下:
#include<iostream>#include<stdio.h>#include<math.h>#include<algorithm>using namespace std;const int MAXN = 10000 + 5;int x[MAXN], r[MAXN];struct qu{ double a, b;} q[MAXN];bool cmp(qu a, qu b) //按 b 升序排列{ return a.b < b.b;}int main(){ int t, n, w, h; cin >>t; while(t--) { cin >>n >>w >>h; int s = 0; int tx, tr; while(n--) { cin >>tx >>tr; if(2 * tr > h) //只保存装置直径比草坪宽度大的 { x[s ++] = tx; r[s - 1] = tr; } } if(s == 0) { cout <<0 <<endl; continue; } h /= 2; //宽度减半,求区间的 a,b for(int i = 0; i < s; i ++) { q[i].a = x[i] - sqrt(r[i] * r[i] - h * h); q[i].b = x[i] + sqrt(r[i] * r[i] - h * h); } sort(q, q + s, cmp); //排序 double sum = 0; int cnt = 0; while(sum < w) { double len = 0; //当前能覆盖的长度 for(int i = 0; i < s; i ++) //对每个闭区间判断 if(q[i].a <= sum && q[i].b - len > sum) //选择满足条件的且最优的 { len = q[i].b - sum; } if(len == 0) //有的区间覆盖不到 { cnt = 0; break; } sum += len; //覆盖位置后移 cnt ++; //装置数增加 } cout <<cnt <<endl; } return 0;}
1 0
- NYOJ 12 喷水装置(二)
- NYOJ 12 喷水装置(二)
- nyoj 12 喷水装置(二)
- NYOJ 题目12喷水装置(二)
- NYOJ 12 喷水装置(二)
- Nyoj 12 喷水装置(二)
- NYOJ 12 喷水装置(二)
- NYOJ 12 喷水装置(二)
- nyoj 12 喷水装置(二)
- NYOJ 12 喷水装置(二)
- NYOJ-12-喷水装置(二)
- nyoj 12 喷水装置(二)
- NYOJ--12--喷水装置(二)
- NYOJ 12 喷水装置(二)
- nyoj 12 喷水装置(二)
- NYOJ-12 喷水装置(二)
- nyoj 12 喷水装置(二)
- nyoj 12 喷水装置(二)
- cocos2dx 3.2 学习篇之一(简单UI界面的添加(续上篇))
- mysql 引用php中变量查询
- 1028. List Sorting (25)
- Mac上多种字体名称的获取
- 阿里MYSQL数据搬运工具 otter安装配置
- NYOJ 12 喷水装置(二)
- SDP学习
- Oracle优化一个视图发现的问题。
- C++队列
- 文件搜索软件Everything
- 怎么将excel转换pdf在线转换
- 输入两个数,算他们的最小公倍数和最大公约数
- 电池动画的实现
- QT+VS2012安装配置