uva10382(贪心算法---区间覆盖问题)
来源:互联网 发布:日本人彻底疯了 知乎 编辑:程序博客网 时间:2024/05/29 16:32
https://vjudge.net/problem/UVA-10382(uva10382 点击打开题目链接)
区间覆盖问题:数轴上有n个闭区间【a-i,b-i】(i是下标),选择尽量少的区间覆盖一条指定线段【s,t】。
思路:转化成草坪矩形上边界(或下边界)的区间覆盖问题。
分析:因为圆的圆心都在草坪中间,所以如果能覆盖矩形的上边界,就一定能覆盖矩形的下边界。每个圆形洒水器的洒水范围(即n个闭区间)可以通过勾股定理求得,因此就转化为了在矩形上边界这条线段(长度为l)上的区间覆盖问题。
(算法竞赛入门经典)该类题的突破口仍然是区间包含和排序扫描,不过要先进行一次预处理。每个区间在【s,t】外的部分都应该先被切掉,因为他们的存在是毫无意义的。预处理后,在相互包含的情况下,小区间显然不应该考虑。(明白是明白了,不过具体到题目就不清楚怎么预处理了)。
把各区间按照a(区间左侧端点)从小到大排序。如果区间1的左端点大于s,无解(因为其他区间的起点更大,不可能覆盖到s点),否则选择起点小于s的最长区间(至于怎么选择最长区间,这道题就卡在这儿了,看了好多题解代码,最后终于理解的差不多了)。选择此区间【a-i,b-i】后,新的起点应该设置为b-i,并且忽略所有区间在b-i之前的部分,就像预处理一样。
代码:
#include <iostream>#include <string>#include <cstring>#include <algorithm>#include <cmath>#include <vector>#include <cstdio>#include <map>#include <cstdlib>#define pi 2*acos(0)using namespace std;const int maxn = 10000 + 10;struct node{ double l,r; node(double ll,double rr):l(ll),r(rr){} bool operator < (const node x)const//重载小于运算符,进行排序(该题是按照左侧端点从小到大排序,有时候也按照右侧端点排序) { return l < x.l; }};vector<node> v;int main(){ int n; double l,w; while(~scanf("%d%lf%lf",&n,&l,&w)) { v.clear();//清空很重要 int a,b; for(int i = 0;i < n;i++) { scanf("%d%d",&a,&b); if(b * 2.0 <= w)//特例判断,如果整个圆都在矩形里面,一定不选 continue; double p = sqrt((b*1.0)*(b*1.0) - (w/2.0)*(w/2.0));//勾股定理,求出半个区间长度,这里结合图形好好理解,如果理解不了,就做不出题目来。 v.push_back(node(a - p,a + p));//将区间长度存入容器 } sort(v.begin(),v.end());//切记:排序!!! int ans = 1; double sl = 0.0,sr = 0.0;//之前看的代码有这一部分,去掉之后仍然ac,因为下面的循环包含了这种情况// if(v.empty() || v[0].l > 0.0)// {// printf("-1\n");// continue;// } for(int i = 0;i < v.size();i++) { if(v[i].l <= sl)//左侧的点比左界限小,但是要选一个最长的区间 { //如果有多组数据,都满足左侧点比左界限小,那就一直更新右界限,选择最大的区间。 sr = max(sr,v[i].r); } else { //直到左侧的点比左界限大了,计数加一 ans++; sl = sr;//新的起点(或者需要维护的点)设置为‘b-i’(即sr). if(v[i].l > sl)//如果新的区间左侧端点大于起点,不符合情况,跳出循环 break; sr = v[i].r;//否则,更新右边界 } if(sr >= l) break; } if(sr >= l) printf("%d\n",ans); else printf("-1\n"); } return 0;}
- 贪心—区间覆盖,还差的很远啊,继续加油吧。
阅读全文
0 0
- uva10382(贪心算法---区间覆盖问题)
- UVA10382- Watering Grass(区间覆盖问题)
- 贪心算法之区间覆盖问题
- 贪心算法之区间覆盖问题
- C++实现贪心算法-区间覆盖问题
- 区间覆盖问题【贪心】
- 区间覆盖问题 贪心
- 贪心 区间覆盖问题
- 区间覆盖问题(贪心)
- 贪心 区间覆盖问题
- 区间覆盖问题 贪心
- 贪心 -- 区间覆盖问题
- 【贪心】区间覆盖问题
- uva10382 - Watering Grass(区间覆盖变形)
- 基于贪心算法的几类区间覆盖问题
- 基于贪心算法的几类区间覆盖问题
- UVa 10382 - Watering Grass(贪心算法,区间覆盖问题)
- 基于贪心算法的几类区间覆盖问题
- #pragma pack(push,1)与#pragma pack(1)的区别
- I hate it.hdu
- LA 3942 Remember the Word——DP + 字典树
- MapStruct实体间转换
- at命令
- uva10382(贪心算法---区间覆盖问题)
- ubuntu 下ffmpeg3.3的编译
- Excel学习1_Java读取文件中的内容写入excel中
- window下MongoDB的配置与安装
- mybatis PageHelper和pageInfo的相关知识点
- adb remount 系统提示只读文件系统Read-only file system
- 【矩形】【dp】创意吃鱼法
- Python基础入门5--函数
- MyBatis简单的配置