zoukankan      html  css  js  c++  java
  • POJ1328 Radar Installation 贪心

    题目大意

    给出几个点的坐标,雷达的覆盖范围为R,雷达布置在x轴上,问要覆盖这些点,至少需要多少雷达?

    思路

    由点的坐标我们可以得到能控制到该点的区间。由此问题就变成了:给出区间集合(R),求一点集(P),使得任意区间([l,r]in R, exists pin P且pin[l,r])。求这点集元素个数的最小值。
    贪心不是指做出了当前决策后,当前决策就永远不变。如果以后改变了一个决策,但是这个决策对之前的结果没有影响,这仍然成立。

    如果我们把所有区间按左端点大小从小到大排序,那么对于当前区间,我们让它(以后的区间)尽可能在不影响以前区间的被负责情况下,由负责前几个区间的点负责它(们)。
    为什么这么做呢?如果以后的区间全部不由以前的点负责,且知道了安排的最优值:如果以后的区间中存在一个或几个点,它所负责的区间全部可以由以前的区间所负责,那么这个点便是多余的;如果是部分可以由以前的点负责,那么把这些能被以前的点负责的区间由以前的点负责,其余的区间由当前点负责,结果不会变坏。

    那么如何达到这一点呢?我们枚举每一个区间,并让最后一个点位于它所负责的区间的尽可能靠右的位置,(令最后一个点负责的区间集为C)也就是(min_{[l,r]in C}{r})。这样会使以后的区间被这个点所负责的可能性最大。
    为什么呢?令当前点位置为(p)。以后的区间([l,r])不被该点负责的情况为(l>p)。如果把这个点靠左一点,不可能的区间就变大了。

    注意事项

    • 注意(R<0)的情况
    • 因为有多组数据,读入文件数据时,如果发现无解,不能提前跳出。
    • 坐标题,一律用double,且不要用floor。
    #include <cstdio>
    #include <cstdarg>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    const int MAX_RANGE_CNT = 1010, INF = 0x3f3f3f3f;
    
    struct Range
    {
    	double L, R;
    	Range(double l, double r):L(l), R(r){}
    	Range() {};
    }_ranges[MAX_RANGE_CNT];
    int TotRange;
    double R;
    
    bool CmpL(Range a, Range b)
    {
    	return a.L < b.L;
    }
    
    int main()
    {
    	int caseCnt = 0;
    	while (scanf("%d%lf", &TotRange, &R) && (TotRange || R))
    	{
    		caseCnt++;
    		int ans = 0;
    		double pos = -INF;
    		if (R < 0)
    			ans = -1;
    		for (int i = 1; i <= TotRange; i++)
    		{
    			double x, y;
    			scanf("%lf%lf", &x, &y);
    			if (abs(y) > R)
    				ans = -1;
    			else
    			{
    				double Len = (sqrt((double)(R * R - y * y)));
    				_ranges[i] = Range(x - Len, x + Len);
    			}
    		}
    		if(ans != -1)
    		{
    			sort(_ranges + 1, _ranges + TotRange + 1, CmpL);
    			for (int i = 1; i <= TotRange; i++)
    			{
    				if (_ranges[i].L > pos)
    				{
    					ans++;
    					pos = _ranges[i].R;
    				}
    				else
    					pos = min(pos, _ranges[i].R);
    			}
    		}
    		printf("Case %d: %d
    ", caseCnt, ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    指令周期与机器周期
    MFC使用Access数据库
    函数指针的用途
    大端模式和小端模式
    Matlab信号展开
    EL表达式的11个内置对象
    JSP 4个域对象、7个动作指令、9个内置对象
    阿里巴巴java代码规范
    HDDATA基本注意事项
    SVN相关
  • 原文地址:https://www.cnblogs.com/headboy2002/p/9090874.html
Copyright © 2011-2022 走看看