pc 111302 uva 10180 Rope Crisis in Ropeland!
题目描述:
http://www.programming-challenges.com/pg.php?page=downloadproblem&probid=111302&format=html
另外做该题的时候参考了ybfq_wanglang的解题思路,地址如下:
http://hi.baidu.com/ybfq_wanglang/blog/item/9fff3b0d116176206159f33d.html
//该题关键在于判断线段是否与圆相交//具体解释参见代码注释//还有就是该题不用求切点坐标//利用弧度完成圆弧段的长度计算//用到反余弦函数#include <cstdio>#include <cmath>#define eps 1e-8struct point {double x, y;};struct line {point a, b;};//叉积double xmult(point p1, point p2, point p0) {return (p1.x - p0.x) * (p2.y - p0.y) -(p2.x - p0.x) * (p1.y - p0.y);}//计算两点间距离double distance(point p1, point p2) {return sqrt((p1.x - p2.x) * (p1.x - p2.x) +(p1.y - p2.y) * (p1.y - p2.y)); }//计算点到直线距离double disptoline(point p, point l1, point l2) {return fabs(xmult(p, l1, l2)) / distance(l1, l2);}//判断线段(端点都在圆外)和圆相交,不包括端点和相切int intersect_seg_circle(point c, double r, point l1, point l2) {point t = c;t.x += l1.y - l2.y;t.y += l2.x - l1.x;//点t点c构成l1 l2 的垂线,如果l1 l2 在直线t c异侧 ,//且圆心到l1 l2 的距离小于 r,则l1 l2 与圆相交return xmult(l1, c, t) * xmult(l2, c, t) < eps &&disptoline(c, l1, l2) < r;}int main() {point p1, p2, origin; //origin为圆心origin.x = origin.y = 0.0;double r;int ncase;scanf("%d", &ncase);while(ncase--) {scanf("%lf %lf %lf %lf %lf", &p1.x, &p1.y, &p2.x, &p2.y, &r);double d1 = distance(p1, p2); //点p1 p2间的距离if(!intersect_seg_circle(origin, r, p1, p2)) //如果线段与圆不想交printf("%.3lf\n", d1);else {double d2 = distance(origin, p1);double d3 = distance(origin, p2);double d = sqrt(d2 * d2 - r * r);d += sqrt(d3 * d3 - r * r);double t = acos((d2 * d2 + d3 * d3 - d1 * d1) / (2 * d2 * d3));t -= acos(r / d2) + acos(r / d3); //现在t为圆上的绳子对应的圆心角的弧度d += t * r;printf("%.3lf\n", d);}}return 0;}