zoukankan      html  css  js  c++  java
  • 牛客 Guard the empire(贪心)

    首先看到题目求最小覆盖,应该可以想到是贪心类的问题

    题目要求覆盖所有骨龙,首先所有骨龙都会在一段区间内被覆盖,我们可以算出每个骨龙的这段距离。

    之后就是求有多少个点可以将这些区间全部覆盖,这是贪心的经典问题。

    显然是先排序,以第一个点的右端点为初始值,往下遍历,如果某个左端点大于他,那么更新为当前的右端点,++ans

    否则,如果当前的右端点小于他,更新为右端点,这个需要理解一下,因为我们当前的右端点并不能覆盖它,也就是这两个区间是包含关系,所以就用类似反悔的方法,把这个点的右端点设为答案。

    注意double,但是这题如果按右端点排序,更加好写

    #include<bits/stdc++.h>
    #define x first
    #define y second
    using namespace std;
    typedef long long ll;
    typedef pair<double,double> pll;
    const int N=2e5+10;
    pll p[N];
    int d,n;
    void cal(int a,int b,int i){
        p[i].x=(double)a-sqrt(double(d*d-b*b));
        p[i].y=(double)a+sqrt(double(d*d-b*b));
    }
    void work(){
        sort(p+1,p+1+n);
        double pos=p[1].y;
        int ans=1;
        for(int i=2;i<=n;i++){
            if(p[i].x>pos){
                ++ans;
                pos=p[i].y;
            }
            else if(p[i].y<pos)
                pos=p[i].y;
        }
    
        cout<<ans<<endl;
    }
    int main(){
        ios::sync_with_stdio(false);
        int cnt=0;
        while(cin>>n>>d){
            if(!n&&!d)
                return 0;
            int i;
            int flag=0;
            int a,b;
            for(i=1;i<=n;i++){
                cin>>a>>b;
                if(d<b||flag){
                    flag=1;
                    continue;
                }
                cal(a,b,i);
            }
            cout<<"Case "<<++cnt<<":"<<" ";
            if(flag)
                cout<<-1<<endl;
            else{
                work();
            }
        }
    }
    View Code
  • 相关阅读:
    HDU 1813 Escape from Tetris
    BZOJ 2276 Temperature
    BZOJ 4499 线性函数
    BZOJ 3131 淘金
    HDU 5738 Eureka
    POJ 2409 Let it Bead
    POJ 1286 Necklace of Beads
    POJ 1696 Space Ant
    Fox And Jumping
    Recover the String
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12988126.html
Copyright © 2011-2022 走看看