CSP-M4 B - ZJM要抵御宇宙射线 Gym - 270737H

该博客介绍了如何解决一个数学问题,即在已知多个宇宙射线发射点的情况下,找到一个点构建最小面积的圆形保护罩以覆盖所有点。解题思路涉及找到最大距离的最小值,并提供了程序源码实现。输入输出样例及数据组成也进行了详细说明。
摘要由CSDN通过智能技术生成
题目描述

据传,2020年是宇宙射线集中爆发的一年,这和神秘的宇宙狗脱不了干系!但是瑞神和东东忙于正面对决宇宙狗,宇宙射线的抵御工作就落到了ZJM的身上。假设宇宙射线的发射点位于一个平面,ZJM已经通过特殊手段获取了所有宇宙射线的发射点,他们的坐标都是整数。而ZJM要构造一个保护罩,这个保护罩是一个圆形,中心位于一个宇宙射线的发射点上。同时,因为大部分经费都拨给了瑞神,所以ZJM要节省经费,做一个最小面积的保护罩。当ZJM决定好之后,东东来找ZJM一起对抗宇宙狗去了,所以ZJM把问题扔给了你~

输入
输入 第一行一个正整数N,表示宇宙射线发射点的个数
接下来N行,每行两个整数X,Y,表示宇宙射线发射点的位置

输出
输出包括两行
第一行输出保护罩的中心坐标x,y 用空格隔开
第二行输出保护罩半径的平方
(所有输出保留两位小数,如有多解,输出x较小的点,如扔有多解,输入y较小的点)
无行末空格

输入样例
5
0 0
0 1
1 0
0 -1
-1 0
输出样例
0.00 0.00
1.00

数据组成

数据点nxy
1~5n<=100|x|<=10000|y|<=10000
6~10n<=1000|x|<=100000|y|<=100000
解题思路

简单地说,这道题给出了若干个点,要求我们找到一个点,满足这个点到其余各个点的距离的最大值在所有点中是最小的。

这道题可以直接遍历所有可能的结果,输出最佳解。虽然题目要求结果保留两位小数,但因为所有点都是整数坐标,而且题目要求输出的距离是两个点距离的平方,最后也是整数。考虑到给出的数的计算结果会超出int的表示范围,所以最后我们使用long long来记录和处理数据即可。在最后的输出格式化中,使用"%lld.00\n"来输出。

程序源码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdio.h>
using namespace std;

const long long maxdis = 10000000000000; //最大距离标记
struct point //点结构体
{
	long long x; //x轴坐标
	long long y; //y轴坐标
	point() {}
	point(long long x, long long y) :x(x), y(y) {}
};

long long getdis(const point& p1, const point& p2) { //计算两点间距离的平方
	return (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y);
}

point& choosepoint(point& p1, point& p2) { //有多解,选出题目要求的较优的点
	if (p1.x < p2.x) { //如有多解,输出x较小的点
		return p1;
	}
	if (p2.x < p1.x) {
		return p2;
	}
	if (p1.y < p2.y) { //如仍有多解,输入y较小的点
		return p1;
	}
	else {
		return p2;
	}
}


int main() {
	int n;
	scanf("%d", &n);
	point p[1001];
	for (int i = 0; i < n; i++) { //获取输入的点集
		scanf("%lld%lld", &p[i].x, &p[i].y);
	}
	long long mindis = maxdis;
	point maxpoint;

	for (int i = 0; i < n; i++) {
		long long thisround = -1; //存储i这个点到其余各个点的距离的最大值
		long long tmpdis;
		for (int j = 0; j < n; j++) {
			tmpdis = getdis(p[i], p[j]); //计算距离
			if (tmpdis > thisround) thisround = tmpdis;
		}
		if (thisround == mindis) { //i点到其余各个点的距离的最大值和当前最优解相同
			maxpoint = choosepoint(maxpoint, p[i]); //选出最优解
		}
		else if (thisround < mindis) {//i点距离更小,是最优解
			mindis = thisround; //记录下距离
			maxpoint = p[i]; //修改最优解
		}
	}
	printf("%lld.00 %lld.00\n", maxpoint.x, maxpoint.y); //输出最优点的坐标
	printf("%lld.00\n", mindis); //输出最优解的距离

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值