(建图搜索 + 二分查询) O(nlog(n)O(nlog(n)
1, 对所有炸弹按x坐标排序
2,建图 若A可以引爆B则建一条A指向B的边
3,对每一个排雷火箭进行二分查询,找到可能引爆的炸弹的下标的范围
4,找到3中的炸弹后按图搜索即可
#include <bits/stdc++.h>
using namespace std;
#define de(x) cout << x << " ";
#define sf(x) scanf("%d", &x);
#define Pu puts("");
#define ll long long
const int N = 5e4 + 10, M = 1e7 + 10;
int n, m;
int hed[N], nxt[M], var[M], tot;
bool st[N];
int ans;
// 相当于二维数组,作用是记录某点处是否有炸雷
map<pair<int, int>, int> mp;
struct E {
int x, y, r, cnt;
bool operator<(const E& t) const { // 自定义排序,按照从小到大的顺序
if (x != t.x)
return x < t.x;
return y < t.y;
}
} e[N];
int cn; // 去重后的炸雷数量
void add(int x, int y) {
var[++tot] = y;
nxt[tot] = hed[x];
hed[x] = tot;
}
int dfs2(int x) {
st[x] = true;
int res = e[x].cnt;
for (int i = hed[x]; i; i = nxt[i]) {
if (st[var[i]] == true)
continue;
res += dfs2(var[i]);
}
return res;
}
void dfs(int x, int y, int r) {
E e1 = {x - r - 1, y, r};
E e2 = {x + r + 1, y, r};
// 这里运用了二分,我的理解是,找结构体中的第一个参数,也就是x的值
// 第一个大于等于改x值的结构体下标
int l = lower_bound(e + 1, e + cn + 1, e1) - e;
int r1 = lower_bound(e + 1, e + cn + 1, e2) - e;
l = min(cn, l);
r1 = min(cn, r1);
for (int i = l; i <= r1; i++) {
int t1 = abs(e[i].x - x) * abs(e[i].x - x) +
abs(e[i].y - y) * abs(e[i].y - y) - r * r;
if (t1 <= 0 && st[i] == false) {
ans += dfs2(i);
}
}
}
int main() {
cin >> n >> m;
int x, y, r;
for (int i = 1; i <= n; i++) {
sf(x) sf(y) sf(r);
int t1 = mp[{x, y}]; // 判断这点处是否有炸雷
if (t1 == 0) {
e[++cn].x = x;
e[cn].y = y;
e[cn].r = r;
e[cn].cnt++;
mp[{x, y}] = cn;
} else {
e[t1].cnt++;
e[t1].r = max(r, e[t1].r);
}
}
sort(e + 1, e + cn + 1); // 开始建边
for (int i = 1; i <= cn; i++) {
int dis = e[i].r * e[i].r;
for (int j = i - 1; j >= 1; j--) {
int t1 = abs(e[i].x - e[j].x) * abs(e[i].x - e[j].x);
if (t1 > dis)
break;
if (abs(e[i].x - e[j].x) * abs(e[i].x - e[j].x) +
abs(e[i].y - e[j].y) * abs(e[i].y - e[j].y) <=
dis) {
add(i, j);
}
}
for (int j = i + 1; j <= cn; j++) {
int t1 = abs(e[i].x - e[j].x) * abs(e[i].x - e[j].x);
if (t1 > dis)
break;
if (abs(e[j].x - e[i].x) * abs(e[j].x - e[i].x) +
abs(e[j].y - e[i].y) * abs(e[j].y - e[i].y) <=
dis) {
add(i, j);
}
}
}
for (int i = 1; i <= m; i++) {
sf(x) sf(y) sf(r);
dfs(x, y, r);
}
de(ans);
return 0;
}