放砖头

【题目描述】
  你有一个长宽高分别为 A、B、C 的砖头,地上有一个 D*E 的矩形洞,你可以以任何姿
  势尝试把砖头放进洞中,假设洞的深度无穷大,请你判断,你的砖头能否塞进洞中。
【输入数据】
  仅一行,五个实数 A、B、C、D、E。
【输出数据】
  输出 YES/NO

   

正解:(这里有两种方法)

  有很多方法啊(虽然考试的时候我一种也没做出来)

  考试的时候我连可以斜着塞这种情况都没想到qwq

  1.zyz的方法 

 <黑白版>

  矩形ABCD为待塞进洞的砖头 E为直线AD与矩形洞的交点 F为直线BC与矩形洞的交点

  二分BE的长度:

    先取一半 

    如果BE<AD 则说明BE还要再短一点 (使BC与水平线的夹角小一点)

    如果BF<BC  则说明BE还要再长一点(使BC与水平线的夹角大一点)

    当BE又要再长一点 又要再短一点的时候 (即自相矛盾的时候) 就要输出NO了

    当BE既不太长又不太短的时候就为 YES

  另外一个lsy想到的方法(CODE见下) 

  即 在最坏的能塞进去的情况中 矩形ABCD的中心一定与矩形洞的中心重合

  所以我们只要判断在这样的情况下 砖头能否塞进去即可

  怎么判断呢

<彩色版>

  首先我们已经知道AE和EF的长度 (AE=AC/2,AC由勾股定理可求) 可以求出AF

  若AF>坑的长/2 那么直接puts("NO") return 0; 否则 继续

  我们知道HE,AH 可以根据反三角函数求出角EAH

  根据AE,EF 可以求出角EAF 

  相减得到角HAF 

  根据相似可得 角ABG=角HAF

  又知道AB 所以可求AG

  最后判断AF+AG是否大于 坑的长/2 即可

  

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #define db double
 5 using namespace std;
 6 db a,b,c,d,e,f,g,h;
 7 //a:AB b:AD c:砖头高 d:坑宽 e:坑长 f:AC g:AF h:AG
 8 db x,y,z;
 9 //x:角EAH y:角EAF z:角HAF
10 int main()
11 {
12     scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e);
13     if(a>c) swap(a,c); if(b>c) swap(b,c);
14     if(d>e) swap(d,e); if(a>b) swap(a,b);//注意这里 使长,宽对应
15     if(a<=d&&b<=e) {puts("YES");return 0;}
16     f=sqrt(a*a+b*b);
17     g=sqrt((f/2)*(f/2)-(d/2)*(d/2));
18     if(g>e/2) {puts("NO");return 0;}
19     x=atan((a/2)/(b/2));
20     y=asin((d/2)/(f/2));
21     z=x-y; h=a*sin(z);
22     if(g+h>e/2) puts("NO");
23     else puts("YES");
24     return 0;
25 }
法2 View Code

猜你喜欢

转载自www.cnblogs.com/forward777/p/10317030.html