按照紫书的思路,首先从上边界开始找出是否存在连续的相交的圆,一直延伸到下边界,如果存在的话,那么就不能够从左边界走到右边界。如果不存在,那么就更新每个圆和左边界以及右边界的交点坐标(如果存在的话),最后输出。同时注意,如果设定的全局变量记录左边界以及右边界的交点坐标,记得每次输出后要将全局变量重新置为原始值,便于后续的比较操作,具体实现见如下源代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
using namespace std;
int n;
int width = 1000;
double Left=1000.0, Right=1000.0;
typedef struct{
double x, y;
double r;
}node;
bool dfs(int cur,vector<bool>& visit,vector<node>& v){
if (visit[cur]) return false;
visit[cur] = true;
if (v[cur].y <= v[cur].r) return true;
for (int i = 0; i < n; i++){
if (visit[i]) continue;
double distance = sqrt((v[cur].x-v[i].x)*(v[cur].x-v[i].x)
+(v[cur].y-v[i].y)*(v[cur].y-v[i].y));
double radius = v[cur].r + v[i].r;
if (radius >= distance&&dfs(i,visit,v)){
return true;
}
}
int i = cur;
if (v[i].x <= v[i].r){
Left = min(Left, v[i].y - sqrt(v[i].r*v[i].r - v[i].x*v[i].x));
}
if (width - v[i].x <= v[i].r){
double t = width - v[i].x;
Right = min(Right, v[i].y - sqrt(v[i].r*v[i].r - t*t));
}
return false;
}
int main(){
while (cin >> n){
vector<node> v;
for (int i = 0; i < n; i++){
node temp;
cin >> temp.x >> temp.y >> temp.r;
v.push_back(temp);
}
vector<bool> visit(n,false);
bool exist = true;//true表示有解
for (int i = 0; i < n; i++){
if (v[i].y + v[i].r >= width&&dfs(i,visit,v)){
exist = false;
break;
}
}
if (!exist){
cout << "IMPOSSIBLE" << endl;
}
else cout << fixed << setprecision(2) << "0.00 " << Left << " 1000.00 " << Right << endl;
Left = 1000.0;
Right = 1000.0;
}
//system("pause");
return 0;
}