HDU 4454

想了很久,发现其实就只需要三分枚举圆上的点,到矩形的最短很容易就可以求到了。开始时考虑要不要根据矩形相对圆的方位来划分枚举区间,后来发现一定不能这样做的。

注意题目给的是矩形的对角形,但没说哪一条对角线哦,所以,注意。。。被这坑了好久。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

const double PI=3.141592653;
const double eps=1e-8;
const double inf=1e10;
struct Point{
	double x,y;
};
double xmin,ymin,xmax,ymax,r;
Point start,center,first;
double ans;
Point corn[4];

double cal(double ang){
	double x=cos(ang)*first.x-sin(ang)*first.y;
	double y=cos(ang)*first.y+sin(ang)*first.x;
	double l1=sqrt((x-start.x)*(x-start.x)+(y-start.y)*(y-start.y));
	double l2=inf;
	for(int i=0;i<4;i++){
		l2=min(l2,sqrt((x-corn[i].x)*(x-corn[i].x)+(y-corn[i].y)*(y-corn[i].y)));
	}
	if(x-eps>=xmin&&x<=xmax-eps){
		if(y<=ymin-eps){
			l2=min(l2,ymin-y);
		}
		else if(y-eps>=ymax){
			l2=min(l2,y-ymax);
		}
	}
	else if(y-eps>=ymin&&y<=ymax-eps){
		if(x-eps>=xmax){
			l2=min(l2,x-xmax);
		}
		else if(x<=xmin-eps){
			l2=min(l2,xmin-x);
		}
	}
	return l1+l2;
}

int main(){
	double l,r,m,mm;
	double a,b,c,d;
	while(scanf("%lf%lf",&start.x,&start.y)!=EOF){
		if(fabs(start.x)<eps && fabs(start.y)<eps) break;
		scanf("%lf%lf%lf",&center.x,&center.y,&r);
		scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
		xmin=min(a,c); xmax=max(a,c);
		ymin=min(b,d); ymax=max(b,d);
		start.x-=(center.x),start.y-=(center.y);
		xmin-=center.x,xmax-=center.x;
		ymin-=center.y,ymax-=center.y;
		center.x=center.y=0;
		corn[0].x=xmin,corn[0].y=ymin;
		corn[1].x=xmin,corn[1].y=ymax;
		corn[2].x=xmax,corn[2].y=ymin;
		corn[3].x=xmax,corn[3].y=ymax;
		first.x=center.x+r;
		first.y=center.y;
		l=0,r=PI; ans=inf;
		while(l+eps<r){
			m=(r+l)/2;
			mm=(m+r)/2;
			if(cal(m)>cal(mm)){
				l=m;
			}
			else r=mm;
		}
		ans=min(ans,cal(r));
		l=-PI,r=0;
		while(l+eps<r){
			m=(r+l)/2;
			mm=(m+r)/2;
			if(cal(m)>cal(mm)){
				l=m;
			}
			else r=mm;
		}
		ans=min(ans,cal(r));
		printf("%.2lf\n",ans);
	}
	return 0;
}

  

时间: 2024-08-12 18:27:27

HDU 4454的相关文章

hdu 4454 Stealing a Cake(三分)

题目链接:hdu 4454 Stealing a Cake 题目大意:给定一个起始点s,一个圆形,一个矩形.现在从起点开始,移动到圆形再移动到矩形,求最短距离. 解题思路:在圆周上三分即可.即对角度[0,2*pi]三分,计算点和矩形的距离可以选点和矩形四条边的距离最短值. #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std

Hdu 4454 Stealing a Cake(枚举或三分)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4454 思路:枚举角度,确定圆上点的位置,取最小值. 点到矩形最短距离:若点在矩形边所表示的范围内,则到矩形最短距离为x或y坐标到矩形边的距离.否则为点到矩形顶点的距离. #include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<algorithm> #

HDU 4454 Stealing a Cake --枚举

题意: 给一个点,一个圆,一个矩形, 求一条折线,从点出发,到圆,再到矩形的最短距离. 解法: 因为答案要求输出两位小数即可,精确度要求不是很高,于是可以试着爆一发,暴力角度得到圆上的点,然后求个距离,求点到矩形的距离就是求点到四边的距离然后求个最小值,然后总的取个最小值即可. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include &l

HDU 4454 Stealing a Cake(三分暴力枚举)

题目大意:给你一个点,一个圆,一个矩形让你求出来,点到圆然后再到矩形的距离.圆和矩形你可以认为是可以穿过的. 解题思路:三分枚举点到圆的位置,然后求出来总长度,找到一个最小的长度.枚举点的坐标的时候可以枚举角度,也可以枚举坐标.总长度等于点到圆上的点的距离加上圆上的点到矩形四个线段的最小距离的和. PS:输出%0.2lf所以精度要求不高,自我感觉枚举角度会更保证精度. Stealing a Cake Time Limit: 5000/2000 MS (Java/Others)    Memory

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

[hdu 2102]bfs+注意INF

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 感觉这个题非常水,结果一直WA,最后发现居然是0x3f3f3f3f不够大导致的--把INF改成INF+INF就过了. #include<bits/stdc++.h> using namespace std; bool vis[2][15][15]; char s[2][15][15]; const int INF=0x3f3f3f3f; const int fx[]={0,0,1,-1};

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是