牛客小白月赛22 I

本文最后更新于:星期四, 二月 3日 2022, 9:15 晚上

题目传送门

思路:对于每个点都可以通过一些简单计算得到激光枪射中它的最小角度和最大角度,将这些角度排序,枚举起点。

在遍历过程中,对最小角度我们都对这个点进行标记,如果遇到最大角度,那么所有之前标记的点都可以被射中,那么我们就讲这些点的标记清空,最后取最小值即可

时间复杂度O(n2)O(n^2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
*
* Author: Hsueh-
* Date: 2020-03-02 13:10:34
*
* */

#include <bits/stdc++.h>

using namespace std;

#define dbg(x...) \
do { \
cout << #x << " -> "; \
err(x); \
} while (0)

void err() {
cout << endl;
}

template <class T, class... Ts>
void err(const T& arg, const Ts&... args) {
cout << arg << ' ';
err(args...);
}

#define endl "\n"
#define all(A) A.begin(), A.end()
using ll = long long;
using db = double;
using pII = pair<int, int>;

const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int N = 5e2 + 10;
const db eps = 1e-8, PI = acos(-1.0);

int sgn(db x) {
if (fabs(x) < eps)
return 0;
else
return x > 0 ? 1 : -1;
}

struct node {
int type;
int idx;
db angle;

node() {}

node(int type, int idx, db _angle) : type(type), idx(idx) {
angle = fmod(_angle + 2 * PI, 2 * PI);
}

bool operator<(const node& other) const {
if (sgn(angle - other.angle) == 0)
return type < other.type;
else
return angle < other.angle;
}
};

int n, d;
vector<node> vec;
int mark[N];

void RUN() {
cin >> n >> d;
vec.clear();
for (int i = 1; i <= n; ++i) {
db x, y;
cin >> x >> y;
db dis = x * x + y * y;
if (sgn(dis - d * d) <= 0)
continue;
db angle = atan2(y, x);
db sub = asin(d / sqrt(dis));
vec.push_back(node(0, i, angle - sub));
vec.push_back(node(1, i, angle + sub));
}
if (vec.empty()) {
cout << 1 << endl;
return;
}
sort(all(vec));
int res = vec.size() / 2;
// for (auto it : vec) {
// dbg(it.idx);
// }
for (int i = 0, len = vec.size(); i < len; ++i) {
vector<int> l;
memset(mark, 0, sizeof mark);
int tmp = 0;
for (int k = 0; k < len; k++) {
int j = (i + k) % len;
if (vec[j].type == 0) {
mark[vec[j].idx] = true;
l.push_back(vec[j].idx);
} else if (mark[vec[j].idx]) {
tmp++;
for (auto it : l) {
mark[it] = 0;
}
l.clear();
}
}
tmp += l.size();
res = min(res, tmp);
}
cout << res << endl;
}

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
cout << fixed << setprecision(20);

int T;
cin >> T;
for (int cas = 1; cas <= T; ++cas) {
RUN();
}

return 0;
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!