zoukankan      html  css  js  c++  java
  • poj1328

    题意:平面上有一些点,现要求用一些圆心在x轴上的圆(雷达)来覆盖这些点,问最少需要多少雷达。

    分析:我的解法是把点按横坐标排序,然后把每个点的雷达尽量往右放,然后每放一个雷达都要保证雷达左面的岛都被雷达所覆盖。所以我们可以按一个点靠右放完雷达后,再根据后面的在雷达位置左面的点,把雷达向左移。一个雷达经过了移的过程,就一定是能覆盖左面的岛。所以排好序后,只需O(n)。

    注意:unique函数的返回值是结尾指针,所以可以用被注释掉两行的方法来获得数组长度。

    标准方法是把每个点的放置雷达的区间求出,然后按照区间排序。排好序后,从左至右看,当发现下一个区间的起始点大于前面所有区间的最小结束点的时候,答案加一。忽视前面走过的所有点后,对后面进行相同的操作(从左至右看,当发现下一个区间的起始点大于左边未被忽视的所有区间的最小结束点的时候,答案加一)。直到结束。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    const int maxn = 1001;
    
    struct Point
    {
    	int x, y;
    } point[maxn];
    
    int n, d, ans;
    bool ok;
    
    bool operator < (const Point &a, const Point &b)
    {
    	return a.x < b.x;
    }
    
    bool operator == (const Point &a, const Point &b)
    {
    	return ((a.x == b.x) && (a.y == b.y));
    }
    
    void init()
    {
    	int i;
    
    	ok = true;
    	for (i = 0; i < n; i++)
    	{
    		scanf("%d%d", &point[i].x, &point[i].y);
    		if (point[i].y > d)
    			ok = false;
    	}
    }
    
    double getx(Point &a)
    {
    	return a.x + sqrt(double(d * d - a.y * a.y));
    }
    
    void work()
    {
    	int	i;
    	double x=getx(point[0]);
    
    	ans = 1;
    	for (i = 1; i < n; i++)
    	{
    		double	temp = getx(point[i]);
    		if (point[i].x < x && x > temp)
    		{
    			x = temp;
    			continue;
    		}
    		if (point[i].y * point[i].y + (point[i].x - x) * (point[i].x - x) <= d * d)
    			continue;
    		x = getx(point[i]);
    		ans++;
    	}
    }
    
    int main()
    {
    	int	casenum = 0;
    
    	//freopen("D:\\t.txt", "r", stdin);
    	while (cin >> n >> d && !(n == 0 && d == 0))
    	{
    		casenum++;
    		init();
    		if (!ok)
    		{
    			printf("Case %d: -1\n", casenum);
    			continue;
    		}
    		sort(point, point + n);
    //		Point *p = unique(point, point + n);
    //		n = (p - point);
    		work();
    		printf("Case %d: %d\n", casenum, ans);
    	}
    	return 0;
    }
  • 相关阅读:
    第三课 Spinner的使用
    Deployment failed due to an error in FastDev assembly synchronization.
    第二课 两个视图+数据传输
    第一课 Hello
    Tab的键的妙用
    RelativeLayout相对布局中拖放控件的办法
    更改layout的布局
    关于MultiDataTrigger和MultiTrigger的一些注意事项
    WPF中XAML的触发器的属性,事件 都有那些?以及如何寻找
    EventTrigger
  • 原文地址:https://www.cnblogs.com/rainydays/p/1948682.html
Copyright © 2011-2022 走看看