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;
}