例题1:POJ 1380(矩阵的包含),给你两个矩阵的长和宽,问前面这个矩阵能否包含后面这个矩阵。
(1)、当前面的矩阵的宽<小于后面这个矩阵的宽时,不能包含。
(2)、当前面矩阵的面积<=后面矩阵的面积,不能包含。
(3)、当前面矩阵的长,宽>后矩阵的长,宽,能够包含。
(4)、特别注意前矩阵宽>后矩阵的宽,但是长<后矩阵的长。如图,可能会包含。
判断只需要后面这个矩阵在水平方向上的投影之和<=前面这个矩阵的长。sin∠1=B/sqrt(C*C+D*D),∠1和∠2之间的那个角的正弦值=D/sqrt(C*C+D*D),水平方向的投影和为:
C*cos∠2+D*sin∠2,自己认真看看,具体见代码。
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int main()
{ double A,B,C,D;
int Case;
cin>>Case;
while(Case--)
{ cin>>A>>B>>C>>D;
if(A<B) swap(A,B);
if(C<D) swap(C,D);
if(B<D||A*B<=C*D) puts("Box cannot be dropped.");
else if(A>C&&B>D) puts("Escape is possible.");
else
{ double Dis=sqrt(C*C+D*D);
double a=asin(B/Dis),b=asin(D/Dis);
if(C*cos(a-b)+D*sin(a-b)<=A) puts("Escape is possible.");
else puts("Box cannot be dropped.");
}
}
return 0;
}
例题2:湖南省第六届程序设计竞赛第四题:
描述
在平面直角坐标系下,台球桌是一个左下角在(0,0),右上角在(L,W)的矩形。有一个球心在(x,y),半径为R的圆形母球放在台球桌上(整个球都在台球桌内)。受撞击后,球沿极角为a的射线(即:x正半轴逆时针旋转到此射线的角度为a)飞出,每次碰到球桌时均发生完全弹性碰撞(球的速率不变,反射角等于入射角)。
如果球的速率为v,s个时间单位之后球心在什么地方?
输入
输入文件最多包含25组测试数据,每个数据仅一行,包含8个正整数L,W,x,y,R,a,v,s(100<=L,W<=105, 1<=R<=5,R<=x<=L-R, R<=y<=W-R, 0<=a<360, 1<=v,s<=105),含义见题目描述。L=W=x=y=R=a=v=s=0表示输入结束,你的程序不应当处理这一行。
输出
对于每组数据,输出仅一行,包含两个实数x, y,表明球心坐标为(x,y)。x和y应四舍五入保留两位小数。
样例输入
100 100 80 10 5 90 2 23
110 100 70 10 5 180 1 9999
0 0 0 0 0 0 0 0
样例输出
80.00 56.00
71.00 10.00
分析:将速度方向分解为水平方向的V1=Vcosa,和垂直方向的V2=Vsina。由于是完全弹性碰撞,所以在每个方向的速度大小不变,做匀速直线运动。可以求出每个方向的总长度。
假设经过单位时间s后水平方向的位置变为len1,如果超过X=L-R,这个时候我们应该将这点转移到桌子内部,直接将超出的部分以X=L-R为对称轴求出对称点即可。这个时候位置变为:2(L-R)-len1。反之要是len1<R,这应该以X=R为对称轴将点转移到桌子内部。此时位置变为2R-len1,一直循环知道最终的结果在(R,L-R)即可输出。
垂直方向的分析一样,具体见代码:
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
#define pi acos(-1.0)
struct Point
{ int x,y;
friend istream& operator>>(istream &cin,Point &P)
{ cin>>P.x>>P.y;
}
bool operator==(const int &n) const
{ return x==n&&y==n;
}
};
int main()
{ Point S;
int L,W,R,a,v,s;
while(cin>>L>>W>>S>>R>>a>>v>>s)
{ if(L==0&&W==0&&S==0&&R==0&&a==0&&v==0&&s==0) break;
double v1,v2;
v1=v*cos(a*pi/180); //水平方向速度
v2=v*sin(a*pi/180); //垂直方向速度
double len1,len2;
len1=S.x+v1*s;
len2=S.y+v2*s;
while(len1<=R||len1>=L-R)
{ if(len1<=R) len1=2*R-len1;
if(len1>=L-R) len1=2*(L-R)-len1;
}
while(len2<=R||len2>=W-R)
{ if(len2<=R) len2=2*R-len2;
if(len2>=W-R) len2=2*(W-R)-len2;
}
cout.precision(2);
cout<<fixed<<len1<<" "<<len2<<endl;
}
return 0;
}