【题目描述】
你有一个长宽高分别为 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
2另外一个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 #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 }