智破连环阵
此题目来自 洛谷, 原始题目与提交代码请前往 P1526 [NOI2003] 智破连环阵 - 洛谷。
题目描述
B 国在耗资百亿元之后终于研究出了新式武器——连环阵(Zenith Protected Linked Hybrid Zone)。 传说中,连环阵是一种永不停滞的自发性智能武器。 但经过 A 国间谍的侦察发现,连环阵其实是由 个编号为 的独立武器组成的。 最初, 号武器发挥着攻击作用,其他武器都处在无敌自卫状态。 以后,一旦第 ()号武器被消灭, 秒种以后第 号武器就自动从无敌自卫状态变成攻击状态。 当第 号武器被消灭以后,这个造价昂贵的连环阵就被摧毁了。
为了彻底打击 B 国科学家,A 国军事部长打算用最廉价的武器——炸弹来消灭连环阵。 经过长时间的精密探测,A 国科学家们掌握了连环阵中 个武器的平面坐标,然后确定了 个炸弹的平面坐标并且安放了炸弹。 每个炸弹持续爆炸时间为 分钟。 在引爆时间内,每枚炸弹都可以在瞬间消灭离它平面距离不超过 的、处在攻击状态的 B 国武器。 和连环阵类似,最初 号炸弹持续引爆 分钟时间,然后 号炸弹持续引爆 分钟时间,接着 号炸弹引爆... 以此类推,直到连环阵被摧毁。
显然,不同的序列 消灭连环阵的效果也不同。 好的序列可以在仅使用较少炸弹的情况下就将连环阵摧毁; 坏的序列可能在使用完所有炸弹后仍无法将连环阵摧毁。 现在,请你决定一个最优序列 使得在第 号炸弹引爆的时间内连环阵被摧毁。 这里的 应当尽量小。
输入格式
第一行包含三个整数:、 和 ,分别表示 B 国连环阵由 个武器组成,A 国有 个炸弹可以使用,炸弹攻击范围为 。 以下 行,每行由一对整数 组成,表示第 号武器的平面坐标。 再接下来 行,每行由一对整数 组成,表示第 号炸弹的平面坐标。 输入数据保证随机、无误、并且必然有解。
输出格式
一行包含一个整数 ,表示实际使用的炸弹数。
输入输出样例
输入 #1
4 3 6
0 6
6 6
6 0
0 0
1 5
0 3
1 1
输出 #1
2
说明/提示
对于 的数据,,,,。
各个测试点 秒。
题目解答
本题题解尚未完成/尚未完善, 不足以 AC 通过评判。
已知共有 个武器、 个炸弹 (范围为 )。
为了方便解题,我们可以先定义一个工具类:
- C++
using namespace std;
/**
* 二维点工具类。
* @author CoolCLK
*/
template<typename T>
class Point {
private:
pair<T, T> position;
public:
Point(T x, T y) {
this -> position = pair(x, y);
}
bool isInDistance(Point<T> other, T d) {
T dx = position.first - other.position.first, dy = position.second - other.position.second, dd = d * d;
dx *= dx;
dy *= dy;
return dx + dy <= dd;
}
};
很好,接下来就是获取数据:
- C++
#include <iostream>
#include <vector>
#define repeat(n) for (size_t _= 0; _ < n; _++)
typedef unsigned int u_int;
using namespace std;
void acceptInput() {}
/**
* 接受多个参数的输入。
* @author CoolCLK
*/
template <typename T, typename... Args>
void acceptInput(T& first, Args&... args) {
std::cin >> first;
acceptInput(args...);
}
class Point { /* 此处省略部分代码 */ };
int main() {
u_int M, n, k;
vector<Point<u_int>> weapons;
vector<Point<u_int>> bombs;
acceptInput(M, n, k);
repeat(M) {
u_int x, y;
acceptInput(x, y);
weapons.emplace_back(x, y);
}
repeat(n) {
u_int x, y;
acceptInput(x, y);
bombs.emplace_back(x, y);
}
return 0;
}
很容易发现,我们还有一个条件没有用到:
......
以后,一旦第 i(1≤i<M)号武器被消灭,1 秒种以后第 i+1 号武器就自动从无敌自卫状态变成攻击状态。
......
每个炸弹持续爆炸时间为 5 分钟。
......
同时,为了方便统计,我们可以定义一个长度为 的布尔数组来储存是否用到这个炸弹。
那么,我们来定义它们。
- C++
u_int BOMB_DURATION = 300; // 5min * 60s/min = 300s
vector<bool> bombsUsed(n, false);
之后,我们就只需要关注主方法即可。