POJ 1328 Radar Installation【题解】

这是一道喜闻乐见 的贪心题

感觉这题最大的坑点在 格 式 \blue{格式} ,我因为格式问题 W A \red{WA} WA了至少 10 10 10次。

思路:

感觉这题比较经典,且有一点思维含量,但是考的算法并不高深。 (    所 以 C S P 应 该 不 会 考 ? ?    ) (~~所以CSP应该不会考??~~ ) (  CSP  )题目大意为:一组圆 C i − m C_{i-m} Cim的纵坐标已经固定,横坐标不确定,半径为 d d d。给定一组点 P 1 − n P_{1-n} P1n,求 m m m的最小值使得这 n n n个点均在这些圆内。

至此问题已经被我们转化为了计算几何题。我们定义结构体

struct point
{
    
    
	int x;int y;
	double l;double r;
};point p[1005];

来储存这些点。我们不妨反过来想:既然圆的半径已经固定,那么对于一个点 P i P_i Pi,能包含其的圆 C i C_i Ci的圆心横坐标范围被唯一确定,由勾股定理可以得到:
x C ∈ [ x p − d 2 − y p 2 , x p + d 2 − p 2 ] x_C\in[x_p-\sqrt{d^2-y_p^2},x_p+\sqrt{d^2-p^2}] xC[xpd2yp2 ,xp+d2p2 ]
将这些区间左端点做递增排序,就能类似于种树问题的贪心了。
A C   c o d e : \green{AC\space code:} AC code:

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;

struct point
{
    
    
	int x;int y;
	double l;double r;
};point p[1005];

int n,d,cnt=1;
int flag=true;

inline double cal_del(point p)
{
    
    
	double delta=d*d*1.0-p.y*p.y;
	return sqrt(delta);	
}

inline bool cmp(point p1,point p2)
{
    
    
	return p1.l<p2.l;
}

int main()
{
    
    
	while(cin>>n>>d)
	{
    
    
		if(n==0||d==0) break; 
		for(int i=1;i<=n;i++)
		{
    
    
			int x0,y0;
			cin>>x0>>y0;
			if(y0>d) flag=false;
			p[i].x=x0;
			p[i].y=y0;
			p[i].l=x0-cal_del(p[i]);
			p[i].r=x0+cal_del(p[i]);
		}
		if(!flag)
		{
    
    
			cout<<"Case "<<cnt<<": "<<-1<<endl;
		}
		else
		{
    
    
			sort(p+1,p+n+1,cmp);
			int tot=1;
			int now=1;
			for(int i=2;i<=n;i++)
			{
    
    
				if(p[i].l>p[now].r)
				{
    
    
					tot++;
					now=i;
				}
				else if(p[i].r<p[now].r)
				{
    
    
					now=i;
				}
			}
			cout<<"Case "<<cnt<<": "<<tot<<endl;
			for(int i=1;i<=n;i++)
			{
    
    
				cout<<p[i].l<<" ";
			}			
		}
		cnt++;
	}
	return 0;
}

最后注意输出格式!

猜你喜欢

转载自blog.csdn.net/qq_62444770/article/details/120598966
今日推荐