zoukankan      html  css  js  c++  java
  • luogu题解 UVA1615 【Highway】

    • 题目链接:

      https://www.luogu.org/problemnew/show/UVA1615

    • 分析:

      首先这里的距离是欧几里得距离而不是曼哈顿距离。

      然后我们对于每个点,求出在公路上保持D范围内最远的两个端点,这两个端点构成一个区间,我们要做的就是选出尽量少的点使所有区间至少有一个点,就是典型的区间选点问题。

      怎么做呢?把所有区间右端点从小到大排序,如果右端点相同左端点小的在前面。

      达到贪心的目的,我们设一个pos=-inf,然后遍历所有区间,如果pos>该区间左端点,cnt+1,pos=区间右端点,然后结合之前的排序方式就不难理解。

    • 注意:

      • 可能有些人不知道怎么求左右端点,这要用到一点解析几何知识,每个点((a,b))构成一个圆的方程((x-a)^2+(y-a)^2=d^2),然后将(y=0)带入就求出两个横坐标

      • 有多组数据

    • 代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cctype>
    #include <cmath>
    using namespace std;
    const int maxn=1000005;
    struct Seg{
    	double l,r;
    	bool operator <(const Seg &b)const{
    		if(r==b.r)return l>b.l;
    		return r<b.r;
    	}
    }seg[maxn];
    double l,d;
    int n;
    int main(){
    	
    	while(scanf("%lf %lf %d",&l,&d,&n)!=EOF){
    	int cnt=0;
    	for(register int i=1;i<=n;i++){
    		double x,y;
    		scanf("%lf %lf",&x,&y);
    		double sqr=sqrt(d*d-y*y);
    		seg[i].l=max(0.0,-sqr+x);
    		seg[i].r=min(l,sqr+x);
    	}
    	sort(seg+1,seg+1+n);
    	double pos=-19260817.0;
    	for(register int i=1;i<=n;i++){
    		if(seg[i].l>pos){
    			pos=seg[i].r;
    			cnt++;
    		}
    	}
    	printf("%d
    ",cnt);
    	memset(seg,0,sizeof(seg));
        }
    		return 0;
    }
    
  • 相关阅读:
    Oracle登录报错-ORA-00119
    Oracle11g配置监听
    Python Turtle模块的简单应用
    Turtle模块基本方法和使用(画布)
    python+selenium自动化禅道登录测试
    Xlrd模块读取Excel文件数据
    Selenium原理
    Axure中的登陆界面和动画轮播
    SQL Server创建用户并分配权限
    EF实体框架创建方法
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/9089877.html
Copyright © 2011-2022 走看看