CCF CSP 2020-9-1 称检测点查询 C语言100分

本文介绍了一种C语言实现的方法,用于根据市民位置查询最近的三个核酸检测点。通过结构体存储检测点信息,利用平方距离公式计算市民与各点的距离,并采用快速排序和冒泡排序相结合的方式找出最近的三个点。代码简洁高效,适用于小规模数据处理。
摘要由CSDN通过智能技术生成

CCF CSP 2020-9-1 称检测点查询 C语言100分

称检测点查询 完成时间11-14 10:54 代码长度1.097KB C 正确 100分 耗时15ms 代码长度2.550MB

题目背景
2020 年 6 月 8 日,国务院联防联控机制发布《关于加快推进新冠病毒核酸检测的实施意见》,提出对“密切接触者”等八类重点人群“应检尽检”,其他人群“愿检尽检”。

问题描述
某市设有 n 个核酸检测点,编号从 1 到 n,其中 i 号检测点的位置可以表示为一个平面整数坐标(xi, yi)。

为方便预约核酸检测,请根据市民所在位置(x, y) ,查询距其最近的三个检测点。
多个检测点距离相同时,编号较小的视为更近。

输入格式
输入共 n + 1 行。

第一行包含用空格分隔的三个整数 n、x 和 y,表示检测点总数和市民所在位置。

第二行到第 n + 1 行依次输入 n 个检测点的坐标。第 i + 1 行(1<= i <= n)包含用空格分隔的两个整数 xi 和 yi ,表示 i 号检测点所在位置。

输出格式
输出共三行,按距离从近到远,依次输出距离该市民最近的三个检测点编号。

样例输入1
3 2 2
2 2
2 3
2 4
样例输出1
1
2
3
样例输入2
5 0 1
-1 0
0 0
1 0
0 2
-1 2
样例输出2
2
4
1

评测用例规模与约定
全部的测试点满足,3<=n<=200,所有坐标均为整数且绝对值不超过1000 。

提示
市民到第 i 号检测点的距离 Di 可由如下公式算出:
Di2 = (x - xi)2+(y - yi)2

思路:
使用结构体将同一个数据的数据关联起来,方便思考
使用pow() sqrt()求距离,sqrt()可以不用
先按距离远近排序(快速排序),再在同距离的结构体中按序号排序(冒泡)最后输出结构体数组的前3个就可。

#include<stdio.h>
#include<math.h>
typedef struct s
{
	int num;
	float x;
	float y;
	float dis;
}S;
int quicksort(S s[],int left,int right);
int main()
{
	int i,j,n,X,Y;
	S temp;
	scanf("%d %d %d",&n,&X,&Y);
	S s[n];
	for(i=0;i<n;i++)
	{
		scanf("%f %f",&s[i].x,&s[i].y);
		s[i].num=i+1;  //检测点序号
	}
	for(i=0;i<n;i++)
	{
		s[i].dis=pow((s[i].x-X),2)+pow((s[i].y-Y),2);  //不使用sqrt()也可以 
	}
	quicksort(s, 0, n-1);
	for(i=0;i<n-1;i++)   //同距离按序号大小排序
	{
		for(j=i+1;j<n;j++)
		{
			if(s[i].dis!=s[j].dis)
			{
				break;
			}
			if(s[i].num>s[j].num)
			{
				temp=s[i];
				s[i]=s[j];
				s[j]=temp;
			}
		}	
	}
	printf("%d\n%d\n%d",s[0].num,s[1].num,s[2].num);
	return 0;
 } 
 
int quicksort(S s[],int left,int right)
 {
 	int i,j,m;
 	S temp;
 	i=left;
 	j=right;
 	temp=s[left];
 	if(left>right)
 	{
 		return 0;
	}
	while(i!=j)
	{
	 	while(s[j].dis>=temp.dis&&i<j)
	 	{
	 		j--;
		}
		if(s[j].dis<temp.dis&&i<j)
		{
		 	s[i++]=s[j];
		}
		while(s[i].dis<=temp.dis&&i<j)
	 	{
	 		i++;
		}
		if(s[i].dis>temp.dis&&i<j)
		{
		 	s[j--]=s[i];
		}
	}
	s[i]=temp;
	quicksort(s, left, i-1);
	quicksort(s, i+1, right);
	return 0;
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JY_0329

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值