poj 1328

题目大意: 在坐标轴上给出一些点,给定圆的半径,在坐标轴上尽量找少的圆心,使所有圆形能把这些点包含起来。


显然是个贪心问题:


思路1:每次都保证左边的点能全部达到,尽量往右边的点靠。这个思路本身没问题但我写的时候却出了点问题,(建议(自己)重写)。


思路2:两个点包含不包含在一个圆内,看这两个点的左右临界点。


如果 right1>right2 显然,(如果可能)肯定能放在同一个圆,否则就不行。



<span style="font-size:14px;">Source Code
Problem: 1328		User: wuluxun
Memory: 244K		Time: 63MS
Language: C++		Result: Accepted

    Source Code

    #include <iostream>
    #include <algorithm>
    #include <stdlib.h>
    #include <math.h>

    using namespace std;

    struct point
    {
    	double left, right;
    }p[2010], temp;

    bool operator < (point a, point b)
    {
    	return a.left < b.left;
    }

    int main()
    {
    	int n;
    	double r;
    	int kase = 0;
    	while (cin >> n >> r && (n || r))
    	{
    		bool flag = false;
    		for (int i = 0; i < n; i++)
    		{
    			double a, b;
    			cin >> a >> b;
    			if (fabs(b) > r)
    			{
    				flag = true;
    			}
    			else
    			{
    				p[i].left = a * 1.0 - sqrt(r * r - b * b);
    				p[i].right = a * 1.0 + sqrt(r * r - b * b);
    			}
    		}
    		cout << "Case " << ++kase << ": ";
    		if (flag)
    		{
    			cout << -1 << endl;
    		}
    		else
    		{
    			int countt = 1;
    			sort(p, p + n);
    			temp = p[0];
    			
    			for (int i = 1; i < n; i++)
    			{
    				if (p[i].left > temp.right)
    				{
    					countt++;
    					temp = p[i];
    				}
    				else if (p[i].right < temp.right)
    				{
    					temp = p[i];
    				}
    			}
    			cout << countt << endl;
    		}
    	}
    }
</span>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值