Codeforces Round #340 -C - Watering Flowers-暴力+set

 

http://codeforces.com/contest/617/problem/C

题意:给你n个点,2个圆心,

让你选择半径r1,r2使得两个圆能完整覆盖所有点,并且要求 r1*r1+r2*r2最小


思路:

val1 : 点x到圆心1的距离

val2:点x到圆心2的距离


先把n个点 放入一个 按照 val2排序递减的set


把n个点按val1递增排序

按val1值从小到大遍历

从set里去掉点x,

设圆1的半径为 dis(点x到r1)也即val1;

那么x之前的点 肯定都被 圆1覆盖了,其余没被覆盖的点都在set里面,那么取set的第一个点的val2值作为圆2半径,就可保证2圆覆盖所有点

更新ans=min(ans,r1*r1+r2*r2);


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <iostream>
using namespace std;   
double eps=0.000001; 
 
struct node
{
	__int64 x,y;
	__int64 val1;
	__int64 val2;
	bool operator ==(const node& b)const
	{
	return x==b.x&&y==b.y;
	}
	bool operator <(const node& b)const
	{
	return val2>b.val2;
	}

};
node tm1[2005];
__int64 cmp1(node &a,node&b)
{return a.val1<b.val1;}
set<node> sb;
int main()
{
	__int64 n,i;
	__int64 x1,x2,y2,y1;
	scanf("%I64d",&n);
	scanf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2);
	for (i=1;i<=n;i++)
	{
		scanf("%I64d %I64d",&tm1[i].x,&tm1[i].y); 
		tm1[i].val1=(tm1[i].x-x1)*(tm1[i].x-x1)+(tm1[i].y-y1)*(tm1[i].y-y1);
		tm1[i].val2=(tm1[i].x-x2)*(tm1[i].x-x2)+(tm1[i].y-y2)*(tm1[i].y-y2);
		sb.insert(tm1[i]);
	}  
	sort(tm1+1,tm1+n+1,cmp1);
	set<node>::iterator it;
	it=sb.begin();
	__int64 dis1=  it->val2;
	__int64 ans=dis1;
	for (i=1;i<=n;i++)
	{
		sb.erase(tm1[i]);
		__int64 dis1=0;
		if(!sb.empty())
		{
			it=sb.begin();
		  dis1=  it->val2;
		}
		__int64 tmp_ans=tm1[i].val1+dis1;
		if (tmp_ans<ans) ans=tmp_ans;
	}
	printf ("%I64d\n",ans);
	return 0;
}


Codeforces Round #340 (Div. 2)

你可能感兴趣的:(Codeforces Round #340 -C - Watering Flowers-暴力+set)