1981 单位圆套点

极限情况 

所谓极限情况就是单位圆上有两个点,稍微动一下就会损失一个点,覆盖点最多的圆一定有一个是这种圆(当然当N=1的时候是个例外)。朴素想法是先固定两个点,然后枚举其他的点是否在这两个点决定的两个圆内,朴素得掉渣我就不写了。

更快的算法是,先只固定一个点i,该点的单位圆与其他点j的单位圆相交,形成i圆上的一段弧,该弧被j圆覆盖。最终圆如果在该弧上,则一定能覆盖j点。那么问题归结于找出i圆上被覆盖次数最多的一段弧。

至于弧的表示,用两个极角表示,分别为起始和终止,类似于一个区间。枚举完其他点之后,得到N-1个区间。将其排序后,从前往后扫描,碰到起始计数+1,碰到终止计数-1,同时更新答案。

至于极角的求解,三角函数我全忘光了……查了查维基才记起来,如图:

其中,acos的定义如下:

atan2的定义如下:

#include<cstdio>
#include<cmath>
#include<algorithm>
 
using namespace std;
 
#define MAX_N 300 + 16
 
typedef double p_type;
 
struct Point
{
	p_type x, y;
 
	Point(){}
 
	Point(p_type x, p_type y) : x(x), y(y){}
} ps[MAX_N];
 
struct PolarAngle
{
	p_type angle;
	bool flag;	// 起点或终点
 
	const bool operator<(const PolarAngle &other)
	{
		return angle < other.angle;
	}
} as[MAX_N];
 
inline p_type distance_of(const Point &P, const Point &Q)
{
	return sqrt((P.x - Q.x) * (P.x - Q.x) + (P.y - Q.y) * (P.y - Q.y));
}
 
inline int solve(const int& n, const p_type& r)
{
	int result = 1;
	for (int i = 0; i < n; ++i)
	{
		int m = 0;
		double d;
		for (int j = 0; j < n; ++j)
		{
			if (i != j && (d = distance_of(ps[i], ps[j])) <= 2)
			{
				double phi = acos(d / 2);
				double theta = atan2(ps[j].y - ps[i].y, ps[j].x - ps[i].x);
				as[m].angle = theta - phi, as[m++].flag = 1;
				as[m].angle = theta + phi, as[m++].flag = 0;
			}
		}
		sort(as, as + m);
		for (int sum = 1, j = 0; j < m; ++j)
		{
			if (as[j].flag)
				++sum;
			else
				--sum;
			result = max(result, sum);
		}
	}
	return result;
}
 
///SubMain//
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	int N;
	while (scanf("%d", &N), N)
	{
		for (int i = 0; i < N; ++i)
		{
			scanf("%lf%lf", &ps[i].x, &ps[i].y);
		}
		printf("%d\n", solve(N, 1.0));
	}
#ifndef ONLINE_JUDGE
	fclose(stdin);
	fclose(stdout);
	system("out.txt");
#endif
	return 0;
}

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 、可私信6博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 、可私信6博主看论文后选择购买源代码。
### 回答1: MATLAB大圆套小圆图像重建正投影程序是用于将一个由大圆套小圆组成的图像进行正投影重建的程序。 首先,我们需要定义一个由大圆套小圆组成的图案。可以使用MATLAB的图形工具箱中的函数创建这个图案,例如使用circle函数创建圆,或者使用line函数创建直线连接圆心。然后,我们可以将所有的圆坐标和直线坐标存储在一个矩阵中,用于后续的正投影重建。 接下来,我们需要定义一个正投影平面,通常选择为一个方形平面。我们可以使用meshgrid函数创建这个正投影平面,并定义其大小和分辨率。 然后,我们可以使用MATLAB的图像处理工具箱中的函数将大圆套小圆图案投影到定义好的正投影平面上。可以使用线性插值方法,根据圆和直线的坐标进行插值计算。可以使用imresize函数调整图案的大小和分辨率。 最后,我们可以将正投影结果保存为图像文件,或使用MATLAB的图形工具箱中的imshow函数显示出来。可以根据需要增加一些图像显示设置,如设置颜色映射或添加标题和标签。 总而言之,MATLAB大圆套小圆图像重建正投影程序主要是通过定义圆和直线的坐标、创建正投影平面、使用插值计算投影结果、保存或显示正投影图像等步骤来实现的。 ### 回答2: MATLAB是一种常用的科学计算与数据分析软件,可以通过编写程序来实现各种图像处理和重建的功能。下面是一个MATLAB程序,实现大圆套小圆图像重建的正投影。 1. 首先,我们可以创建一个空白图像矩阵,用于存储重建后的图像。可以使用以下命令创建一个尺寸为nxn的空白图像矩阵: `image = zeros(n);` 2. 接下来,我们可以通过遍历图像矩阵的每个像素位置,判断该像素是否在大圆范围内或小圆范围内。如果在大圆范围内,则像素值为1;如果在小圆范围内,则像素值为0。 ```matlab for i = 1:n for j = 1:n distance_to_center = sqrt((i-n/2)^2 + (j-n/2)^2); if distance_to_center <= R_big && distance_to_center >= R_small image(i,j) = 1; end end end ``` 在上述代码中,n代表图像矩阵的尺寸,R_big代表大圆半径,R_small代表小圆半径。 3. 最后,我们可以显示并保存重建后的图像: ```matlab imshow(image); % 显示图像 imwrite(image, 'reconstructed_image.png'); % 保存图像 ``` 以上是一个简单的MATLAB程序,实现了大圆套小圆图像的正投影重建。通过设置合适的大圆半径和小圆半径,可以得到不同形状的重建图像。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值