放砖头

      LALALA  

【题目描述】

你有一个长宽高分别为 A、B、C 的砖头,地上有一个 D*E 的矩形洞,你可以以任何姿 势尝试把砖头放进洞中,假设洞的深度无穷大,请你判断,你的砖头能否塞进洞中。

【输入数据】 仅一行,五个实数 A、B、C、D、E。

【输出数据】 输出 YES/NO

【输入样例】 1.0 2.0 1.5 1.5 1.0

【输出样例】 YES

【数据约定】 输入中出现的所有数均至少为 1,至多为 10,小数部分最多一位。

正解:(这里有两种方法,都有code 见下)

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

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

  1.zyz的方法 

 <黑白版>

 

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

  二分BE的长度:(下界为0 上界为AB长度)

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

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

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

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

 

  另外一个lsy想到的方法 

  即 在最坏的能塞进去的情况中 矩形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,l,r,mid;
 7 //a:AB b:AD c:砖头高 d:坑宽 e:坑长
 8 bool ck(db x,db y) {return fabs(x-y)<1e-3;}
 9 int main()
10 {
11     scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e);
12     if(a>c) swap(a,c); if(b>c) swap(b,c);
13     if(d>e) swap(d,e); if(a>b) swap(a,b);
14     l=0.00;r=a;
15     if(a<=d&&b<=e) {puts("YES");return 0;}
16     while(!ck(l,r)) {
17         mid=(l+r)/2;
18         if(b>a*(e-mid)/(sqrt(a*a-mid*mid))) l=mid;
19         else if(b>a*(d-sqrt(a*a-mid*mid))/mid) r=mid;
20         else {puts("YES");return 0;}
21     }
22     puts("NO");
23     return 0;
24 }
法1 View Code
 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

 

posted @ 2019-01-24 21:47  DTTTTTTT  阅读(266)  评论(0编辑  收藏  举报