CCF-CSP第20次认证第1题 --《称检测点查询》

3292. 称检测点查询 - AcWing题库

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

某市设有 nn 个核酸检测点,编号从 11 到 nn,其中 ii 号检测点的位置可以表示为一个平面整数坐标 (xi,yi)(xi,yi)。

为方便预约核酸检测,请根据市民所在位置 (X,Y)(X,Y),查询距其最近的三个检测点。

多个检测点距离相同时,编号较小的视为更近。

输入格式

输入共 n+1n+1 行。

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

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

输出格式

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

数据范围

全部的测试点满足,3≤n≤2003≤n≤200,所有坐标均为整数且绝对值不超过 10001000。

输入样例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
样例2解释

1.png

提示

市民到第 ii 号检测点的距离 Di 可由如下公式算出:

D2i=(X−xi)2+(Y−yi)2

 题解:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int n, X, Y;
	cin>>n>>X>>Y;
	set<pair<int, int>> mySet;
	for(int i=0;i<n;i++){
		int x, y;
		cin>>x>>y;
		mySet.insert(make_pair((X - x) * (X - x) + (Y - y) * (Y - y), i+1));
	}
    int count = 0;
    for (const auto& entry : mySet) {
        cout << entry.second << endl;
        count++;
        if (count == 3) break; // 只输出前三个元素
    }
	return 0;
}

思路:

一开始的想法是计算出每个坐标的距离,然后存进pair里,利用pair的比较原则,但是发现pair只能存两个元素即一对键值对,需要借助其他容器。

然后想的是map,但是排序比较需要自定义函数,试了一下,错了。

又想到了set,因为set有自动排序特性,不需要再自定义函数比较原则。

set<pair<int, int>> mySet;

mySet.insert(make_pair((X - x) * (X - x) + (Y - y) * (Y - y), i+1));
    }

注意使用方法,不同于之前的set的定义和初始化,我还是第一次见。

#include <bits/stdc++.h>
using namespace std;

// 自定义比较函数对象
//struct Cmp {
//    bool operator()(const pair<int, int>& a, const pair<int, int>& b) const {
//        if (a.first != b.first) {
//            return a.first < b.first; // 先比较 first
//        }
//        return a.second < b.second;  // 如果 first 相等,再比较 second
//    }
//};

int main()
{
	int n, X, Y;
	cin>>n>>X>>Y;
	//vector<int> dis(n);
    //map<pair<int, int>, Cmp> myMap;
	//pair<int, int> p;
	set<pair<int, int>> mySet;
	for(int i=0;i<n;i++){
		int x, y;
		cin>>x>>y;
		//dis[i] = (X - x) * (X - x) + (Y - y) * (Y - y);
		//myMap.insert({(X - x) * (X - x) + (Y - y) * (Y - y), i});
		mySet.insert(make_pair((X - x) * (X - x) + (Y - y) * (Y - y), i+1));
	}
    int count = 0;
    for (const auto& entry : mySet) {
        cout << entry.second << endl;
        count++;
        if (count == 3) break; // 只输出前三个元素
    }
	return 0;
}

 注释的地方是更改的。

续:---------------------

看了一个佬@Sherry1122113388的题解:AcWing 3292. 称检测点查询 - AcWing

#include<iostream>
#include<algorithm>
using namespace std;
#include<utility>
const int N=210;
pair<int,int> q[N];
int x,y,a,b,n;

int main(){
    scanf("%d",&n);
    scanf("%d%d",&x,&y);
    for(int i=1;i<=n;i++){
        cin >>a>>b;
        q[i].first=(a-x)*(a-x)+(b-y)*(b-y);
        q[i].second=i;
    }
    sort(q+1,q+n+1);
    for(int i=1;i<4;i++)    cout <<q[i].second<<endl;
    return 0;
}

解决:使用一个pair数组,解决了上面我的pair只能存一对的想法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值