题目: 1033 the cover circle
地址: http://www.acdream.net/problem.php?id=1033
思路:
1. 这一道题目的意思是2个大小相同的圆,去覆盖一个矩形,多大的半径才能使圆的覆盖面积最大。
2. 先假设一个球的情况,可以将变大变小的球比作气球,那么当气球碰壁的时候圆覆盖的面积最大,可以发现一个球一定处在一条边的中线上。
3. 那么当2个球的时候,要使面积最大那么必要条件就是碰壁,其次就是两球相互触碰,那么我们发现将2球的距离拉的足够的远,也就(0 , 0),(w,h)的位置,然后在不断的吹大,同时和长边和短边触碰,由于是球,所以点成45度角移动,那么球的半径最小为0,最大为窄边的1/2.
4. 那么我们会在满足以上两个条件设置2个半径,一个是到壁的距离r1,一个是两球心的距离的1/2, r2,那么比较,当r1>r2说明气球吹大了,当r1<r2时说明气球吹小了。
5.那么可以使用二分法求解:输入->确定左右边界的值->二分法(确定r1,r2->比较->重新赋值缩小范围)->输出
最后注意:题目很坑,w,h没有说明谁是长边,一定要比较,这里我认为长比宽长,所以没有判断错了很多次,o(︶︿︶)o 唉
代码如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
int main(void)
{
double w, h; /*w为长,h为宽*/
double l, r, r1; /*l左边界,r右边界,r1中间*/
double x,y,r2; /*靠近右上的点的坐标*/
while ( scanf ("%lf%lf",&w,&h) != EOF )
{
if(w<h) /*比较输入边的大小*/
{
r1=w;
w=h;
h=r1;
}
l = 0; /*左边界*/
r = h/2; /*右边界*/
while (r-l>0.000001) /*使精度足够的大*/
{
r1 = (r+l)/2; /*r1 到壁距离*/
x=w-r1;
y=h-r1;
r2= sqrt ((x - r1) * (x - r1) + (y - r1) * (y - r1 ))/2;
if ( r1 >= r2 )
{
r=r1;
}
else
{
l=r1;
}
}
printf("%.3lf\n",l);
}
return 0;
}
/**************************************************************
Problem: 1033
Language: C++
Result: Accepted
Time:10 ms
Memory:1012 kb
****************************************************************/
最后注意:题目很坑,w,h没有说明谁是长边,一定要比较,这里我认为长比宽长,所以没有判断错了很多次,o(︶︿︶)o 唉