题目
原题链接:点这里
思路
- 将一个点扩成一个圆
- 二分圆的半径,如果当前圆能覆盖矩形的四个角,说明它能覆盖矩形
- 如果不能,则将矩形分割为四个小矩形,递归判断
- 递归边界
l < eps && r < eps
,这种情况可以把l,r看为一个点,就说明必然没有圆能覆盖到了,返回false
代码实现
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
using namespace std;
#define debug(x) cerr << #x << ": " << x << '\n'
#define bd cerr << "----------------------" << el
#define el '\n'
#define cl putchar('\n')
#define pb push_back
#define eb emplace_back
#define x first
#define y second
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
#define loop(i, a, b) for (int i = (a); i < (b); i++)
#define dwn(i, a, b) for (int i = (a); i >= (b); i--)
#define ceil(a, b) (a + (b - 1)) / b
#define ms(a, x) memset(a, x, sizeof(a))
#define inf 0x3f3f3f3f
#define db double
typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<db, db> PDD;
typedef vector<int> vci;
typedef map<int, int> mii;
typedef mii::iterator mii_it;
const int N = 1e5 + 10, M = 2e6 + 10, E = 1e3 + 10, md = 1e9 + 7;
const double PI = acos(-1), eps = 1e-6;
int T, n, m;
int L, W;
PII p[N];
db s;
int dcmp(db x, db y)
{
if(fabs(x - y) < eps) return 0;
if(x < y) return -1;
return 1;
}
db get_dist(db x, db y, int i)
{
return (p[i].x - x) * (p[i].x - x) + (p[i].y - y) * (p[i].y - y);
}
bool in(db x, db y, int i)
{
return get_dist(x, y, i) <= s;
}
bool check(db x, db y, db l, db w)
{
if(l < eps && w < eps) //划分这种程度等价于一个点,说明这个地方永远不可能被覆盖到了
return false;
rep (i, 1, n)//一个圆能覆盖这个矩形的四个角
if (in(x, y, i) && in(x + l, y, i) && in(x, y + w, i) && in (x + l, y + w, i))
return true;
db L = l / 2, W = w / 2;
return check(x, y, L, W) && check(x + L, y, L, W) && check(x, y + W, L, W) && check(x + L, y + W, L, W);
//当前没有一个圆可以覆盖矩形的四个角,看看是否有圆,能分别覆盖四个小矩形
}
int main()
{
cin.tie(0);
cout.tie(0);
cin >> L >> W >> n;
rep(i, 1, n)
cin >> p[i].x >> p[i].y;
db l = 0 ,r = 20000, mid ;
//把一个点扩成圆,二分半径,康康是否有一个圆能覆盖四个角
while(dcmp(l, r) < 0)
{
mid = (l + r) / 2;
s = mid * mid;
if (check(0, 0, L, W))
r = mid;
else
l = mid;
}
printf("%.7lf",r);
return 0;
}