题意:
一个凸多边形和(m)个光源,问最少选择几个光源使得多边形所有边都被照亮
思路:
对于每个光源,处理出能照到的边,即为区间完全覆盖问题,但是区间是环形的,枚举起点处理
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-8;
const int maxn = 10010;
int sgn(double x) { return fabs(x) < eps ? 0 : (x > 0 ? 1 : -1); }
struct Point {
double x, y;
Point() {}
Point(double _x, double _y) {
x = _x;
y = _y;
}
void input() {
scanf("%lf%lf", &x, &y);
}
Point operator-(const Point &b) const {
return Point(x - b.x, y - b.y);
}
double operator^(const Point &b) const {
return x * b.y - y * b.x;
}
};
double cross(Point A, Point B, Point C) {
return (B - A) ^ (C - A);
}
Point p[maxn], a[maxn];
struct s {
int l, r, id;
} b[maxn];
vector<int> ans;
int solve(int st, int num, int len) {
int last = 0, far = 0, cnt = 0, now;
int start = b[st].l;
for (int i = 0; i < num; i++) {
if (last >= len) return cnt;
if (b[i].l - start <= last) {
if (far < b[i].r - start) {
far = b[i].r - start;
now = b[i].id;
}
} else {
cnt++;
ans.push_back(now);
last = far;
if (b[i].l - start <= last) {
if (far < b[i].r - start) {
far = b[i].r - start;
now = b[i].id;
}
} else
return -1;
}
}
if (last < len && far >= len) {
ans.push_back(now);
return cnt + 1;
}
if (far < len) return -1;
return cnt;
}
int main() {
int n, m, t;
scanf("%d", &t);
while (t--) {
ans.clear();
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) p[i].input();
for (int i = 0; i < n; i++) p[i + n] = p[i];
for (int i = 0; i < m; i++) a[i].input();
for (int i = 0; i < m; i++) {
int j = 0;
while (sgn(cross(p[j], p[j + 1], a[i])) < 0) j++;
while (sgn(cross(p[j], p[j + 1], a[i])) > 0) j++;
int pos = j;
while (sgn(cross(p[j], p[j + 1], a[i])) < 0) j++;
b[i * 2] = {pos, j, i + 1};
b[i * 2 + 1] = {pos + n, j + n, i + 1};
}
m *= 2;
sort(b, b + m, [&](s x, s y) {
return x.l < y.l;
});
vector<int> vec;
int sz = 1e9;
for (int i = 0; i < m; i++) {
ans.clear();
int res = solve(i, m, n);
if (res == -1) continue;
if (res < sz) {
sz = res;
vec = ans;
}
}
if (sz == 1e9)
puts("-1");
else {
printf("%d
", (int)vec.size());
for (int i = 0; i < vec.size(); i++)
printf("%d%c", vec[i], "
"[i == vec.size() - 1]);
}
}
return 0;
}