【题目链接】click here~~
【题目大意】求多个圆与线段相交的部分占整个线段的百分比。
【解题思路】
求出符合要求的交线段,排序一遍圆心。最后求并。
代码:
#include <bits/stdc++.h>
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
struct node
{
double x,y,l,r;
} Map[105];
bool cmp(node a, node b)
{
if(a.l == b.l) return a.r < b.r;
return a.l < b.l;
}
double solve(double a)
{
if(a<0) return 0;
if(a>1) return 1;
return a;
}
int main()
{
int n,m,i,j;
double x1, y1, x2, y2;
double x, y, r;
double a, b, c, d, bi1, bi2;
while(cin>>n&&n)
{
cin>>x1>>y1>>x2>>y2;
int res= 0;
for(i = 0; i < n; i ++)
{
cin >> x >> y >> r;
a = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
b = 2*((x1-x)*(x2-x1) + (y1-y)*(y2-y1));
c = (x1-x)*(x1-x) + (y1-y)*(y1-y) - r*r;
d = b*b-4*a*c; //求解直线与圆相交方程
if (d<= 0) continue;
bi1 = solve((-b+sqrt(d)) / (2*a));
bi2 = solve((-b-sqrt(d)) / (2*a));
if(bi2 < bi1) swap(bi1, bi2);
Map[res].l = bi1; // bi1,bi2为在线段上的比例。
Map[res ++].r=bi2;
}
if(res==0)
{
cout <<"0.00" << endl;
continue;
}
sort(Map, Map+res, cmp); //按照圆心排序
double ans = 0, bi1 = Map[0].l, bi2 = Map[0].r;
for(i = 1; i < res; i ++) // 重叠的部分。
{
if(Map[i].l > bi2)
{
ans += bi2 - bi1;
bi1 = Map[i].l;
bi2 = Map[i].r;
}
else
{
bi2 = max(bi2, Map[i].r);
}
}
ans+=bi2-bi1;
printf("%.2f\n", ans*100);
}
return 0;
}
BNU 7536 && HDU 3425 Coverage (圆与直线相交)
原文地址:http://blog.csdn.net/u013050857/article/details/45012515