题目回顾:
阴阳龙https://sim.csp.thusaac.com/contest/31/problem/3
C++满分题解
思路概述
从输入到输出,整理逻辑为:
接下来设计数据结构:
首先需要一个结构来存放员工和阴阳龙位置:
struct location {
long long x; //横坐标
long long y; //纵坐标
int pID; //员工编号,阴阳龙编号为0
location(long long x = 0, long long y = 0, int pID = 0) {
this->pID = pID;
this->x = x;
this->y = y;
}
};
求解k时,刚开始我朴素的定义了一个函数来计算两个location之间的距离:
long long l_distance(location l1, location l2){
if(l1.x==l2.x) //在x轴方向
return abs(l1.y-l2.y)==0? 1e10:abs(l1.y-l2.y);
else if(l1.y==l2.y) //在y轴方向
return abs(l1.x-l2.x);
else if(abs(l1.x-l2.x) == abs(l1.y-l2.y)) //在对角线方向
return abs(l1.x-l2.x);
else return 1e10;
}
于是,我朴素的进行如下操作求解,这样一套操作完成,时间复杂度为:
#伪代码 |
1. 输入,初始化地图和人员 |
2. 阴阳龙开始刷新 |
3. 计算阴阳龙刷新位置到所有人员的最短距离 (d1) |
4. 计算阴阳龙到边界的最短距离 (d2) |
5. k = d1<d2 ? d1:0 |
6. 更新人员 |
7. 计算最终结果 |
end |
提交之后发现只通过了用例2,剩下的都是运行超时(用例2的q最小)。
于是开始改进。可以发现,在计算阴阳龙刷新位置到人员的最短距离时,并不是所有的人员都需要参与计算,只需要考虑八个方向上的点即可,这是简化之一。同时,在查找一个方向(数轴)上距离某位置最近的左右两侧的点时,进行二分查找可以将时间复杂度降低,这是简化之二: