您的位置:首页 > 其它

ZOJ 1608. Two Circles and a Rectangle

2012-06-04 19:29 162 查看
    地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1608

    题意:给你两个圆形(半径分别为 r1 、r2 )和一个矩形(矩形边长为 a 和 b),判断两个圆是否能放于矩形内。其中 a, b, r1, r2 都是浮点数。

    分析:考虑两个圆能放入的一个最基本的必要条件就是:半径最大的圆至少要能放入,那么小圆自然也能放入,即 min( a, b ) >= max( r1, r2 ) * 2;

    接下来分析能否放入的临界点。假设矩形的长边是 a,短边是 b,大圆半径是 r1, 小圆半径是 r2,满足上述条件时( b >= r1 * 2 ),r2 很小的情况可以不必考虑。

    另 b 略大于 r1 * 2,设想右侧短边是一个可以滑动的挡板,从远处向左侧短边滑动。 当 a 非常大时,两个圆靠近成相切状态,两个圆可以同时与底边相切(但这不是最节省空间状态)。当矩形向内收缩时,达到下图所示状态时(两个圆分别和矩形相对的边相切,即理想状态下矩形每条边只和一个圆相切,只有一个切点),将不能继续收缩,即到达临界点:

    zoj1608

#include <math.h>
#include <stdio.h>

int judge(double a, double b, double r1, double r2)
{
double maxside = a > b ? a : b;
double minside = a < b ? a : b;
double maxR = r1 > r2 ? r1 : r2;
double minR = r1 < r2 ? r1 : r2;

if(minside < maxR * 2)
return 0;

double z = r1 + r2;
double x = a - z;
double y = b - z;

if(x * x + y * y < z * z)
return 0;
else
return 1;
}

int main(int argc, char* argv[])
{
double a, b, r1, r2;
while(scanf("%lf %lf %lf %lf", &a, &b, &r1, &r2) != EOF)
{
if(judge(a, b, r1, r2)) printf("Yes\n");
else printf("No\n");
}
return 0;
}


    最后,题目中的“You can safely assume x < y, where x and y are float-point numbers, if x < y + 0.01.” 这句话是什么意思呢,其实就是让你不必关注浮点数的大小比较,其两个浮点数的大小关系将是非常显著的。我推测出题者的意思就是测试数据的浮点数关系不是大于就是小于(明显不能放入或明显能放入),而不会出现非常接近(非常靠近能否放入的临界点),例如 1.00001 和 1.00002 这样的让人比较纠结的情况。所以上面的代码中不必考虑浮点计算和比较时的精度问题,即分析和代码中的所有等于号“=”应该都是可以去掉的。如果两个浮点数非常接近,例如给出一个矩形的边分别是 5.0000 和 4.9999,满足 5.0000 < (4.9999 + 0.1 ),则导致可以认为 5.0000 < 4.9999,这显然是荒唐的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: