Stealing a Cake

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1164    Accepted Submission(s): 320
Problem Description
There is a big round cake on the ground. A small ant plans to steal a small piece of cake. He starts from a certain point, reaches the cake, and then carry the piece back home. He does not want to be detected, so he is going to design a shortest path to achieve his goal.

The big cake can be considered as a circle on a 2D plane. The ant’s home can be considered as a rectangle. The ant can walk through the cake. Please find out the shortest path for the poor ant.

 
Input
The input consists of several test cases.

The first line of each test case contains x,y, representing the coordinate of the starting point. The second line contains x, y, r. The center of the cake is point (x,y) and the radius of the cake is r. The third line contains x1,y1,x2,y2, representing the coordinates of two opposite vertices of the rectangle --- the ant's home.

All numbers in the input are real numbers range from -10000 to 10000. It is guaranteed that the cake and the ant's home don't overlap or contact, and the ant's starting point also is not inside the cake or his home, and doesn't contact with the cake or his home.

If the ant touches any part of home, then he is at home.

Input ends with a line of 0 0. There may be a blank line between two test cases.
 
Output
For each test case, print the shortest distance to achieve his goal. Please round the result to 2 digits after decimal point.
 
Sample Input
1 1
-1 1 1
0 -1 1 0
0 2
-1 1 1
0 -1 1 0
0 0
 
Sample Output
1.75
2.00
 
Source


思路:
分析之后,是满足凸型的函数,用三分求最小值。(听说暴力枚举角度也可以过,那就没意思了)

ps:
比赛时,所有的代码都写好了,但是一直WA,一直卡到了比赛结束,好桑心。比赛完后发现是自己矩阵的坐标没统一,我想的是统一,敲却用错了变量,真的太马虎了,把峰峰和泉泉给坑了,真的太不好意思了。

代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
//#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 105
#define MAXN 10005
#define mod 1000000007
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 0.00000001
using namespace std; int n,m;
double x,y,xr,yr,r,x1,Y1,x2,y2,ans;
double le,ri,mid,mmid; double caldist(double xx1,double YY1,double xx2,double yy2)
{
return sqrt((xx1-xx2)*(xx1-xx2)+(YY1-yy2)*(YY1-yy2));
}
double getdist(double k)
{
int i,j;
double xx,yy,d1,d2;
xx=xr+r*cos(k);
yy=yr+r*sin(k);
d1=caldist(xx,yy,x,y);
d2=INF;
if(xx>=x1&&xx<=x2||yy>=Y1&&yy<=y2)
{
if(xx>=x1&&xx<=x2)
{
d2=min(d2,fabs(yy-Y1));
d2=min(d2,fabs(yy-y2));
}
else
{
d2=min(d2,fabs(xx-x1));
d2=min(d2,fabs(xx-x2));
}
}
else
{
d2=min(d2,caldist(xx,yy,x1,Y1));
d2=min(d2,caldist(xx,yy,x2,y2));
d2=min(d2,caldist(xx,yy,x1,y2));
d2=min(d2,caldist(xx,yy,x2,Y1));
}
return d1+d2;
}
void solve()
{
int i,j;
double d1,d2,tle=le,tri=ri;
while(ri-le>eps)
{
mid=(le+ri)/2.0;
mmid=(mid+ri)/2.0;
d1=getdist(mid);
d2=getdist(mmid);
if(d1<d2) ri=mmid;
else le=mid;
}
ans=d1;
le=tri;
ri=tle+2*pi;
while(ri-le>eps)
{
mid=(le+ri)/2.0;
mmid=(mid+ri)/2.0;
d1=getdist(mid);
d2=getdist(mmid);
if(d1<d2) ri=mmid;
else le=mid;
}
ans=min(ans,d1);
}
void presolve()
{
int i,j;
double xx1=x1,YY1=Y1,xx2=x2,yy2=y2,tmp;
x1=min(xx1,xx2);
Y1=min(YY1,yy2);
x2=max(xx1,xx2);
y2=max(YY1,yy2);
xx1=xr-x;
YY1=yr-y;
tmp=2*xx1/(2*sqrt(xx1*xx1+YY1*YY1));
le=pi/2+acos(tmp);
ri=le+pi;
}
int main()
{
int i,j;
while(scanf("%lf%lf",&x,&y))
{
if(x==0&&y==0) break ;
scanf("%lf%lf%lf%lf%lf%lf%lf",&xr,&yr,&r,&x1,&Y1,&x2,&y2);
presolve();
solve();
printf("%.2f\n",ans);
}
return 0;
}






 

hdu 4454 Stealing a Cake (三分)的更多相关文章

  1. hdu 4454 Stealing a Cake(三分之二)

    pid=4454" target="_blank" style="">题目链接:hdu 4454 Stealing a Cake 题目大意:给定 ...

  2. HDU 4454 - Stealing a Cake(三分)

    我比较快速的想到了三分,但是我是从0到2*pi区间进行三分,并且漏了一种点到边距离的情况,一直WA了好几次 后来画了下图才发现,0到2*pi区间内是有两个极值的,每个半圆存在一个极值 以下是代码 #i ...

  3. hdu 4454 Stealing a Cake(计算几何:最短距离、枚举/三分)

    题意:已知起点.圆.矩形,要求计算从起点开始,经过圆(和圆上任一点接触即可),到达矩形的路径的最短距离.(可以穿过园). 分析:没什么好的方法,凭感觉圆上的每个点对应最短距离,应该是一个凸函数,用三分 ...

  4. hdu 4454 Stealing a Cake 三分法

    很容易想到三分法求解,不过要分别在0-pi,pi-2pi进行三分. 另外也可以直接暴力枚举…… 代码如下: #include<iostream> #include<stdio.h&g ...

  5. hdu 4454 Stealing a Cake

    简单的计算几何: 可以把0-2*pi分成几千份,然后找出最小的: 也可以用三分: #include<cstdio> #include<cmath> #include<al ...

  6. hdu 4454 Stealing a Cake(三分法)

    给定一个起始点,一个矩形,一个圆,三者互不相交.求从起始点->圆->矩形的最短距离. 自己画一画就知道距离和会是凹函数,不过不是一个凹函数.按与水平向量夹角为圆心角求圆上某点坐标,[0, ...

  7. HDU 4454 Stealing a Cake(枚举角度)

    题目链接 去年杭州现场赛的神题..枚举角度..精度也不用注意.. #include <iostream> #include <cstdio> #include <cstr ...

  8. HDU 4454 Stealing a Cake --枚举

    题意: 给一个点,一个圆,一个矩形, 求一条折线,从点出发,到圆,再到矩形的最短距离. 解法: 因为答案要求输出两位小数即可,精确度要求不是很高,于是可以试着爆一发,暴力角度得到圆上的点,然后求个距离 ...

  9. hdu 4771 Stealing Harry Potter&#39;s Precious(bfs)

    题目链接:hdu 4771 Stealing Harry Potter's Precious 题目大意:在一个N*M的银行里,贼的位置在'@',如今给出n个宝物的位置.如今贼要将全部的宝物拿到手.问最 ...

随机推荐

  1. asp.net预览图片

    Aspx code <table> <tr> <td class="style3"> <asp:Label ID="Label1 ...

  2. js访问 xmldom

    加载XML文档:     var xmlDom = new ActiveXObject("MSXML2.DOMDocument");  xmlDom.load("file ...

  3. Weblogic 部署注意事项

    Weblogic下部署服务注意事项: 1. 解决weblogic与hibernate的jar包冲突问题: 首 先找到该系统的DOMAIN_HOME(即你所建的域所在的位置)如:域empi的DOMAIN ...

  4. oFixed() 方法

    oFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 在本例中,我们将把数字舍入为仅有一位小数的数字: Show the number 13.37 with one decimal ...

  5. Devpexpress 打印预览问题

    devexpress 12 之前报表打印: XtraReports rp1 = new XtraReports(); rp1.ShowPreview(): 即可预览报表: devexpress 13 ...

  6. C语言处理CSV文件的方法(二)

    strtok函数的使用是一个老生常谈的问题了.该函数的作用很大,争议也很大.以下的表述可能与一些资料有区别或者说与你原来的认识有差异,因此,我尽量以实验为证.交代一下实验环境是必要的,win7+vc6 ...

  7. HTML DOM 属性记录

    将HTML DOM中几个容易常用的属性做下记录,需要的朋友可以参考下.     nodeName.nodeValue 以及 nodeType 包含有关于节点的信息. nodeName 属性含有某个节点 ...

  8. 重写javascript浮点运算

    javascript中变量存储时不区分number和float类型,同一按照float存储; javascript使用IEEE 754-2008标准定义的64bit浮点格式存储number,decim ...

  9. how to install git 1.8 rpm

    git版本在低于1.8之前,对于私有项目会出现401的pull失败错误,只能通过升级git版本来解决 It appears that git18 is no longer available from ...

  10. linux开机自动挂载NTFS-WINDOWS分区

    1.安装ntfs-3g-2009.4.4.tgz 2.输入fdisk -l 看一下分区 由此可见:/dev/sda5,6,7 即是windows下的D,E,F盘(NTFS格式). 3.vim /etc ...