!HDU 4173 到点的距离不超过2.5,找最多能被满足的点的个数-简单几何

题意:有n个人参加派对,但是条件是派对地点到他家的距离不能超过2.5,现在要你找一个最佳的派对地点让最多人参加派对。

分析:

题目看起来挺难的,怎么求范围然后包含点?其实一个圆心+半径不就代表一个圆了吗。

枚举求两个点的半径为2.5的圆的圆心,保存起来,然后用这些圆心求所有点到圆心的距离,记录距离小于等于2.5的点的个数,更新结果。200*199/2*200不会超时,计算就是高中基本的数学知识。仔细一些耐心一点就是了。注意计算得到的浮点数判定要用eps。

代码:

#include<iostream>
#include<cmath>
#include<algorithm>
#define eps 1e-8
using namespace std;
int n,ans,cnt;
double x[300],y[300];
struct node{
	double x,y;
}center[40000];
double dis(double a,double b,double c,double d)
{
	return sqrt((a-c)*(a-c)+(b-d)*(b-d));
}
void getcenter(int i,int j)
{
	double midx=(x[i]+x[j])/2.0;
	double midy=(y[i]+y[j])/2.0;
	double k,b;
	if(x[i]-x[j]==0){
		double x1=sqrt(6.25-(midy-y[i])*(midy-y[i]))+x[i];
		double x2=x[i]-sqrt(6.25-(midy-y[i])*(midy-y[i]));
		center[cnt].x=x1,center[cnt++].y=midy;
		center[cnt].x=x2,center[cnt++].y=midy;
	}
	else if(y[i]-y[j]==0){
		double y1=sqrt(6.25-(midx-x[i])*(midx-x[i]))+y[i];
		double y2=y[i]-sqrt(6.25-(midx-x[i])*(midx-x[i]));
		center[cnt].x=midx,center[cnt++].y=y1;
		center[cnt].x=midx,center[cnt++].y=y2;
	}
	else{
		double k1=(y[i]-y[j])/(x[i]-x[j]);
		k=-1.0/k1;
	    b=midy-k*midx;
		double tmp1=(x[i]+k*y[i]-k*b);
		double tmp2=(x[i]+k*y[i]-k*b)*(x[i]+k*y[i]-k*b)-(k*k+1)*(x[i]*x[i]+y[i]*y[i]+b*b-2*b*y[i]-6.25);
		double x1=(tmp1+sqrt(tmp2))/(k*k+1);
		double x2=(tmp1-sqrt(tmp2))/(k*k+1);
		double y1=k*x1+b;
		double y2=k*x2+b;
		center[cnt].x=x1,center[cnt++].y=y1;
		center[cnt].x=x2,center[cnt++].y=y2;
	}

}
int main()
{
     while(cin>>n){
     	cnt=0,ans=1;
     	for(int i=0;i<n;i++) cin>>x[i]>>y[i];
     	for(int i=0;i<n;i++){
     		for(int j=i+1;j<n;j++){
     			if(dis(x[i],y[i],x[j],y[j])<5.0+eps) getcenter(i,j);
     		}
     	}
     	for(int i=0;i<cnt;i++){
     		int tot=0;
     		for(int j=0;j<n;j++){
     			if(dis(x[j],y[j],center[i].x,center[i].y)<2.5+eps) tot++;
     		}
     		ans=max(ans,tot);
     	}
     	cout<<ans<<endl;
     }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-06 00:55:41

!HDU 4173 到点的距离不超过2.5,找最多能被满足的点的个数-简单几何的相关文章

HDU 4173 Party Location(计算几何,枚举)

HDU 4173 题意:已知n(n<=200)位参赛选手的住所坐标,现要邀请尽可能多的选手来参加一个party,而每个选手对于离住所超过2.5Km的party一律不去,求最多可以有多少个选手去参加party. 思路: 不妨先考虑party可能的位置,要尽可能多的邀请到选手参加,则只需考虑party所在位置在某两位住所连线的中点上或某选手住所所在位置,因为这是最大参加party选手数很有可能在的位置. 若其他位置能得到最大参加选手数,那么中点或选手住所也一定可得到.//反证法可得,试着画画就ok~

HDU 4793 Collision + HDU 4798 Skycity 简单几何

HDU 4793 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4793 题意:给一个以(0,0)为圆心半径为R的圆形区域,中间放着一个(0,0)为圆心半径为Rm的圆盘,在坐标(x,y)处(严格在圆形区域外)放着一枚半径为r的硬币,运动方向和速度为(vx,vy),在运动中碰到圆盘时,会按碰撞问题反弹(圆盘是固定不动的),问硬币会在圆形区域里呆多长时间(硬币只要有一点点在圆形区域里就记为硬币在圆形区域内). 思路:首先先计算出硬币在移动过程中如果不与圆盘

hdu Caocao&#39;s Bridges(无向图边双连通分量,找出权值最小的桥)

1 /* 2 题意:给出一个无向图,去掉一条权值最小边,使这个无向图不再连同! 3 4 tm太坑了... 5 1,如果这个无向图开始就是一个非连通图,直接输出0 6 2,重边(两个节点存在多条边, 权值不一样) 7 3,如果找到了桥的最小权值为0,也就是桥上的士兵数为0,那么还是要最少派一个 8 士兵过去炸掉桥! 9 10 思路:假设每两个节点最多只有一条边进行相连! 11 进行tarjan算法,如果该算法调用了超过2次,说明这个原图就是不连通的! 12 否则在tarjan算法中将桥存起来!然后

2014 HDU多校弟八场H题 【找规律把】

看了解题报告,发现看不懂 QAQ 比较简单的解释是这样的: 可以先暴力下达标,然后会发现当前数 和 上一个数 的差值是一个 固定值, 而且等于当前数与i(第i个数)的商, 于是没有规律的部分暴力解决,有规律的套公式 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <cstring&g

HDU 4588 Count The Carries 数位DP || 打表找规律

2013年南京邀请赛的铜牌题...做的很是伤心,另外有两个不太好想到的地方....a 可以等于零,另外a到b的累加和比较大,大约在2^70左右. 首先说一下解题思路. 首先统计出每一位的1的个数,然后统一进位. 设最低位为1,次低位为2,依次类推,ans[]表示这一位上有多少个1,那么有 sum += ans[i]/2,ans[i+1] += ans[i]/2; sum即为答案. 好了,现在问题转化成怎么求ans[]了. 打表查规律比较神奇,上图不说话. 打表的代码 #include <algo

HDU 2147 kiki&#39;s game kiki的游戏(找P/N状态)

题意:给一个有n*m 个格子的棋盘,将一个硬币放在右上角一格,每次可以往左/下/左下移动一格,碰到不能移动的局面者输. 思路:找P/N状态.先将(n,1)归为P状态,那么能一步到达此位置的有3个位置,分别是其上/右/右上的格子.根据这个规律来找,在整个棋盘的格子上标上P和N.可以发现,棋盘上是有规律的,若提供的n和m皆为奇数,则先手输:否则先手赢. 1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4

Hdu 4312-Meeting point-2 切比雪夫距离,曼哈顿距离,前缀和

题目: http://acm.hdu.edu.cn/showproblem.php?pid=4312 Meeting point-2 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1231    Accepted Submission(s): 691 Problem Description It has been ten years s

Hdu 4311-Meeting point-1 曼哈顿距离,前缀和

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4311 Meeting point-1 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3426    Accepted Submission(s): 1131 Problem Description It has been ten years s

!HDU 4311 最小曼哈顿距离-思维&amp;卡时间-(横纵坐标分开算,排序)

题意:有n个点,求以这n个点中的某一点为起点,到各点的曼哈顿距离和最小是多少 分析: 暴力枚举又要超时,这种题一般都是考思维了,多半都是用技巧找到一个高效的方法.个人觉得这题跟上一篇文章的题是一个类型.这种思想要记住. 这题也是用"分治",虽说题目要求的是曼哈顿距离,但是我们为什么真的就要一步到位的求呢,可以横纵坐标分开求,先x排序,然后遍历一遍,求出横坐标的距离,然后y排序,遍历一遍求出坐标的距离加在刚才求得的x的距离上,就是曼哈顿距离了. 这里有一个非常巧妙但是其实很显而易见的东西