从顶向下对节点dfs,如果可以从最顶处扩展到另一边,说明不存在这样的路径
反之一定存在一条路径可以从左边走到右边
可以在dfs的同时求得左边和右边最北的点
代码是看了别人的后自己写的
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
double min(double a, double b)
{
return a < b ? a : b;
}
const int N = 1024;
struct Node
{
double x, y, r;
};
Node ball[N];
bool vis[N];
bool ok;
double in, out;
int n;
void dfs(int u)
{
if (!ok) return;
vis[u] = 1;
if (ball[u].y - ball[u].r <= 0) { ok = 0; return; }
for (int i = 0; i < n; i++)
if (!vis[i] && hypot(ball[u].x - ball[i].x, ball[u].y - ball[i].y) < ball[u].r + ball[i].r)
dfs(i);
if (ball[u].x - ball[u].r <= 0)
in = min(in, ball[u].y - sqrt(ball[u].r*ball[u].r - ball[u].x*ball[u].x));
if (ball[u].x + ball[u].r >= 1000)
out = min(out, ball[u].y - sqrt(ball[u].r*ball[u].r - (1000 - ball[u].x)*(1000 - ball[u].x)));
}
int main()
{
while (cin >> n) {
memset(vis, false, sizeof(vis));
ok = true;
in = out = 1000;
for (int i = 0; i < n; i++)
cin >> ball[i].x >> ball[i].y >> ball[i].r;
for (int i = 0; i < n; i++)
if (!vis[i] && ball[i].y + ball[i].r >= 1000) dfs(i);
if (!ok) cout << "IMPOSSIBLE\n";
else printf("%.2f %.2f %.2f %.2f\n", 0.0, in, 1000.0, out);
}
}
/*
3
500 500 499
0 0 999
1000 1000 200
*/