一、问题描述
二、解答
提醒:本题不宜开方,距离间的比较用平方来比较更好
思路:使用三次for循环,逐一找到最小、第二小、第三小
注:这里用到了limits.h头文件,里面包含了int的最大值INT_MAX
#include<iostream>
#include<math.h>
#include <limits.h>
int d[201] = { 0 };
int dx[201] = { 0};
int dy[201] = { 0 };
int disMin1 = INT_MAX;
int disMin2 = INT_MAX;
int disMin3 = INT_MAX;
//在C++中,INT_MAX和 INT_MIN 这些宏定义存储在 limits.h 或者 climits 头文件中
using namespace std;
int main()
{
int n, X, Y;
cin >> n >> X >> Y;
int x[201] = { 0.0 };
int y[201] = { 0.0 };
for (int i = 1; i <= n; i++)
{
cin >> x[i] >> y[i];
}
int min1 = 0;
int min2 = 0;
int min3 = 0;
for (int i = 1; i <= n; i++)
{
dx[i] = X - x[i];
dy[i] = Y - y[i];
d[i] = pow(dx[i],2) + pow(dy[i],2);
if (d[i] < disMin1)
{
disMin1 = d[i];
min1 = i;
}
}
cout << min1 << endl;
for (int i = 1; i <= n; i++)
{
dx[i] = X - x[i];
dy[i] = Y - y[i];
d[i] = pow(dx[i], 2) + pow(dy[i], 2);
//不能开方,因为由给出的样例输出2,根号2和1系统都会记成1
//即使换成double类型也不行,会导致最终结果错误
if (d[i] < disMin2 && i != min1)
{
disMin2 = d[i];
min2 = i;
}
}
cout << min2 << endl;
for (int i = 1; i <= n; i++)
{
dx[i] = X - x[i];
dy[i] = Y - y[i];
d[i] = pow(dx[i], 2) + pow(dy[i], 2);
if (d[i] < disMin3 && i != min1 && i != min2)
{
disMin3 = d[i];
min3 = i;
}
}
cout << min3 << endl;
return 0;
}
另外,还可以通过构造结构体,使用冒泡排序(Bubble Sort)、插入排序(Insertion Sort)、归并排序(Merge Sort)等排序方法进行排序输出。
可以参考之前看到的博客:csp 20-09-01称检测点查询 & 02风险人群筛查_检测点查询csp-CSDN博客
三、总结
本题我的思路、代码一开始是对的,但是这道题目仍然花费了我不少时间。原因在于我测试样例2的时候,给出的结果一直是1、2、3,我一直以为是我的思路出现了问题,但是想了无数遍、也问了AI无数遍,仍然没发现我的逻辑上有什么问题。最后的最后,我突然想到样例2中的根号2是1.414,四舍五入保留整数是1,显然这样与后面的1一样,就会导致最后的结果出错。于是,我将int类型全部换成了double类型,还是不行。所以,我没有再用sqrt()函数,直接求距离的平方而非距离,这样一来结果果然正确了。
通过本题,我仍然觉得:考虑问题要全面,并且要学会灵活变通。同时我也知道了:我发现问题的能力弱了点,花了那么长时间,才知道到底不对在哪里,但庆幸的是最后还是发现了是哪里出了问题,不然真是竹篮打水一场空了。
另外,我还得出经验:CCF题目所给出的样例以及其他提示非常有用,可以极大帮助我们理解题目意思并找到合适的方法,所以万万不能轻视它而一意孤行,导致耽误很长时间。