timus 1348. Goat in the Garden 2 URAL 点到线段的距离
题目大意:
就是一直羊被拴在一根柱子上,绳长为L, 为要想吃到线段ab上的一排XXX,最少要把绳子拉长多少,要想全吃干净呢?拉长多少?
思路:其实就是一个点到线段之间的距离的问题,最大距离好说,判断下到两点距离那个大那个小就好;最短的距离分两种,看垂足是不是在线段上,怎么看呢?当然不是去求垂足了,应该是利用勾股定理判断是不是钝角,是钝角的话,那判断到哪个端点的距离近就好了; 反之,利用叉积求面积法,等面积法算高……
当然判断垂足是不是在线段上还可以利用叉积判断,pp1与pp2是不是在垂线的两侧……
#include <stdio.h>
#include <cmath>
#define N 110
#include<iostream>
using namespace std;
int n;
struct Point
{
double x;
double y;
}p1,p2,p;
double cross(Point p,Point p1,Point p2)
{
double x1=p1.x-p.x, y1=p1.y-p.y;
double x2=p2.x-p.x,y2=p2.y-p.y;
return x1*y2-x2*y1;
}
double dis2(Point p1,Point p2)
{
return sqrt( pow(p1.x-p2.x,2.0)+pow(p1.y-p2.y,2.0) );
}
double disptoseg(Point p,Point p1,Point p2)
{
if(dis2(p1,p2)==0)return dis2(p,p1);
Point t=p;
t.x+=p1.y-p2.y;
t.y+=p2.x-p1.x;
if(cross(p,t,p1 )*cross(p,t,p2)>=0)
{
return min( dis2(p,p1) , dis2(p,p2) );
}
return fabs( cross(p,p1,p2) )/dis2(p1,p2);
}
double disptoseg2(Point p,Point p1,Point p2)
{
return max( dis2(p,p1),dis2(p,p2) );
}
int main()
{
double l;
while(cin>>p1.x>>p1.y>>p2.x>>p2.y>> p.x>>p.y>>l)
{
double t1=disptoseg(p,p1,p2);
double t2=disptoseg2(p,p1,p2);
if(t1<=l)cout<<0.00<<endl;
else printf("%.2f\n",t1-l);
if(t2<=l)cout<<0.00<<endl;
else printf("%.2f\n",t2-l);
}
return 0;
}