uva11722——直线与矩形相交

题目链接:https://vjudge.net/contest/325833#problem/M

Sidney以相同的概率密度在[t1,t2]到达不高山;Gandtom也以相同的概率密度在[s1,s2]到达。每个人都会停留W时间,问发生事情的概率。/捂脸

Input

第一行组数T(T < 500)。
接下来T行每行包含五个整数t1,t2,s1,s2,w(360≤t1

Output

每组数据输出一行,形式如下。误差在1e-6以内。

Sample Input

2
1000 1040 1000 1040 20
720 750 730 760 16

Sample Output

Case #1: 0.75000000
Case #2: 0.67111111

这个在斌聚专题里是属于计算几何里面的,但是我觉得应该归到基础计算几何里面。

以坐标(t1,s1),(t2,s2)作边平行于坐标轴的矩阵,再作直线y=x+w和y=x-w。

它们之间与矩阵相覆盖的阴影面积占矩阵总面积比就是答案。

很经典的做法,自己画图也能画出来。

相当于求直线与矩形相交的上半部分的面积之差(y=x-w的直线和矩形相交面积减去y=x+w的直线和矩形相交的面积。

即最终只需要写一个函数求出直线和矩形的上半部分的面积。

因为斜率为正,所以总共有5种情况。

不相交,与上边和左边相交,与上边和下边相交,与下边和右边相交,与左边和右边相交。

分类讨论求面积就行了。

#include
using namespace std;
double height,width,s1,s2,t1,t2,w;
double GetArea(double w){
	double tx=s2-w;
	double bx=s1-w;
	double ly=t1+w;
	double ry=t2+w;
	//分别对应线段和矩形相交的四种情况 
	bool onLeft=(ly<=s2&&ly>=s1);
	bool onRight=(ry<=s2&&ry>=s1);
	bool onTop=(tx<=t2&&tx>=t1);
	bool onBottom=(bx<=t2&&bx>=t1);
	if (onLeft&&onTop)//相交于左边和上边 
		return(tx-t1)*(s2-ly)*0.5;
	if (onLeft&&onRight)//相交于左边和右边 
		return((tx-t1)*(s2-ly)-(tx-t2)*(s2-ry))*0.5;
	if (onTop&&onBottom)//相交于上边和下边 
		return((tx-t1)*(s2-ly)-(s1-ly)*(bx-t1))*0.5;
	if (onBottom&&onRight)//相交于下边和右边 
		return(height*width)-(t2-bx)*(ry-s1)*0.5;
	return ly<=s1?height*width:0;//特殊情况,和矩形没有交点 
}
int main(){
	int T;
	scanf("%d",&T);
	for(int kcase=1;kcase<=T;kcase++){
		scanf("%lf%lf%lf%lf%lf",&t1,&t2,&s1,&s2,&w);
		width=t2-t1;
		height=s2-s1;
		double area=(t2-t1)*(s2-s1);
		double ans1=GetArea(w);//求的是线段和矩形相交的线段上面的面积 
		double ans2=GetArea(-w);
		printf("Case #%d: %.8lf\n",kcase,(ans2-ans1)/area); 
	}
	return 0;
} 

 

你可能感兴趣的:(计算几何)