题目大意:给你一个点,一个圆,一个矩形让你求出来,点到圆然后再到矩形的距离。圆和矩形你可以认为是可以穿过的。
解题思路:三分枚举点到圆的位置,然后求出来总长度,找到一个最小的长度。枚举点的坐标的时候可以枚举角度,也可以枚举坐标。总长度等于点到圆上的点的距离加上圆上的点到矩形四个线段的最小距离的和。
PS:输出%0.2lf所以精度要求不高,自我感觉枚举角度会更保证精度。
1 1 -1 1 1 0 -1 1 0 0 2 -1 1 1 0 -1 1 0 0 0
1.75 2.00
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <ctime>
#include <map>
#include <set>
#define eps 1e-9
///#define M 1000100
///#define LL __int64
#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define zero(x) ((fabs(x)<eps)?0:x)
#define mod 1000000007
#define Read() freopen("autocomplete.in","r",stdin)
#define Write() freopen("autocomplete.out","w",stdout)
#define Cin() ios::sync_with_stdio(false)
using namespace std;
const int maxn = 50100;
struct point
{
double x, y;
};
struct Line
{
point a, b;
};
point p[10];
double r;
double xmult(point p1, point p2, point xp)
{
return (p1.x-xp.x)*(p2.y-xp.y) - (p2.x-xp.x)*(p1.y-xp.y);
}
double Distance(point a, point b)
{
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)+eps);
}
double disptoseg(point xp, Line l)
{
point t = xp;
t.x += l.a.y-l.b.y;
t.y += l.b.x-l.a.x;
if(xmult(l.a, t, xp)*xmult(l.b , t, xp) > eps)
{
return Distance(xp, l.a) < Distance(xp, l.b)
? Distance(xp, l.a):Distance(xp, l.b);
}
return fabs(xmult(xp, l.a, l.b))/Distance(l.a, l.b);
}
bool cmp(point a, point b)
{
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
point aa;
double ShortDis(point x)
{
Line l1, l2, l3, l4;
l1.a.x = p[0].x;
l1.a.y = p[0].y;
l1.b.x = p[1].x;
l1.b.y = p[1].y;
l2.a.x = p[0].x;
l2.a.y = p[0].y;
l2.b.x = p[2].x;
l2.b.y = p[2].y;
l3.a.x = p[1].x;
l3.a.y = p[1].y;
l3.b.x = p[3].x;
l3.b.y = p[3].y;
l4.a.x = p[2].x;
l4.a.y = p[2].y;
l4.b.x = p[3].x;
l4.b.y = p[3].y;
double sx1 = min(disptoseg(x, l1), disptoseg(x, l2));
double sx2 = min(disptoseg(x, l3), disptoseg(x, l4));
return min(sx1, sx2);
}
double Del(double x)
{
point xp;
xp.x = x;
xp.y = -1*sqrt(r*r-x*x);
double sum = Distance(xp, aa);
sum += ShortDis(xp);
return sum;
}
double Del1(double x)
{
point xp;
xp.x = x;
xp.y = sqrt(r*r-x*x);
double sum = Distance(xp, aa);
sum += ShortDis(xp);
return sum;
}
int main()
{
while(~scanf("%lf %lf",&aa.x, &aa.y))
{
if(aa.x == 0 && aa.y == 0)
break;
double dx, dy;
scanf("%lf %lf %lf", &dx, &dy, &r);
aa.x -= dx;
aa.y -= dy;
scanf("%lf %lf",&p[0].x, &p[0].y);
p[0].x -= dx;
p[0].y -= dy;
scanf("%lf %lf",&p[1].x, &p[1].y);
p[1].x -= dx;
p[1].y -= dy;
p[2].x = p[0].x;
p[2].y = p[1].y;
p[3].x = p[1].x;
p[3].y = p[0].y;
sort(p, p+4, cmp);
double Min;
double left = -r;
double right = r;
while(right-left > eps)
{
double mid = (right+left)/2.0;
double rmid = (mid+right)/2.0;
double x1 = Del(mid);
double x2 = Del(rmid);
if(x1 < x2) right = rmid;
else left = mid;
}
Min = Del(right);
left = -r;
right = r;
while(right-left > eps)
{
double mid = (right+left)/2.0;
double rmid = (mid+right)/2.0;
double x1 = Del1(mid);
double x2 = Del1(rmid);
if(x1 < x2) right = rmid;
else left = mid;
}
Min = min(Min, Del1(right));
printf("%.2lf\n",Min);
}
}
HDU 4454 Stealing a Cake(三分暴力枚举)
原文:http://blog.csdn.net/xu12110501127/article/details/43529935