原题:1332
题意:给出n个半径为r的城市(圆),一个爆炸半径为R的炸弹,若炸弹爆炸时把整个城市覆盖,那么就认定为毁灭了这个城市,问最多毁灭多少个城市。
解:首先使得 R=R-r , 那么炸弹只要覆盖圆心就可以毁灭这个城市(注意R<0)的情况。然后利用每两个城市来确定两个半径为R的圆,再扫描爆炸的覆盖点即可
#include <iostream>
using namespace std;
#include <math.h>
int a[200][3], n, r, ans = 1;
template <typename T>
T sqr(T x) {
return x*x;
}
const double eps = 1e-9;
void check(double x, double y) {
int sum = 0;
for (int i = 1; i <= n; i++) {
if (r-sqrt(sqr(x-a[i][1])+sqr(y-a[i][2])) > -eps) sum++;
}
if (sum > ans) ans = sum;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i][1] >> a[i][2];
int r1, r2;
cin >> r1 >> r2;
r = r1-r2;
if (r < 0) {
cout << 0 << endl;
return 0;
}
if (r == 0) {
cout << 1 << endl;
return 0;
}
for (int i = 1; i <= n; i++)
for (int j = i+1; j <= n; j++) {
double x, y, vx, vy, l, p, v1, v2;
x = a[i][1]+a[j][1];
y = a[i][2]+a[j][2];
x /= 2.0; y /= 2.0;
p = sqrt(sqr(a[i][1]-a[j][1])+sqr(a[i][2]-a[j][2]))/2.0;
if (r-p < -eps) continue;
if (r-p < eps) l = 0;
else l = sqrt(sqr(r)-sqr(p));
v1 = a[j][1]-a[i][1];
v2 = a[j][2]-a[i][2];
vx = v2;
vy = -v1;
double len = sqrt(sqr(vx)+sqr(vy));
vx /= len;
vy /= len;
check(x+vx*l, y+vy*l);
check(x-vx*l, y-vy*l);
}
cout << ans << endl;
}