http://uva.onlinejudge.org/external/117/11722.pdf
Problem
Solution
求概率方法就是lrj的方法。怎么求面积比,又不要分太多情况讨论呢?首先,线段与直线相交怎么判断,直线与直线求交点怎么求,然后,怎么把四边形的面积转换为三个三角形面积相加,怎么判断两条直线之间没有夹四边形的情况?解决这些情况就行了,基本模板大白书都有。
My code
#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
#define peter cout<<"i am peter"<<endl
#define input freopen("data.txt","r",stdin)
#define randin srand((unsigned int)time(NULL))
#define INT (0x3f3f3f3f)*2
#define LL (0x3f3f3f3f3f3f3f3f)*2
#define MAXN
#define N
#define M
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const double eps=1e-9;
int dcmp(double x){
if(fabs(x)<eps) return 0;
else if(x<0) return -1;
else return 1;
}
int t1,t2,s1,s2,w;
struct Point{
double x,y;
Point(){};
Point(double xx,double yy){
x=xx,y=yy;
}
};
typedef Point Vector;
Vector operator +(const Vector a,const Vector b){
return Vector(a.x+b.x,a.y+b.y);
}
Vector operator -(const Vector a,const Vector b){
return Vector(a.x-b.x,a.y-b.y);
}
double operator *(const Vector a,const Vector b){
return a.x*b.x+a.y*b.y;
}
double operator %(const Vector a,const Vector b){
return a.x*b.y-a.y*b.x;
}
Vector operator*(const Vector a,const double b){
return Vector(a.x*b,a.y*b);
}
Vector operator*(const double b,const Vector a){
return Vector(a.x*b,a.y*b);
}
bool operator==(const Point a,const Point b){
return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
Point Poi_LineInterLine(Point p,Vector v,Point q,Vector w){
Vector pq=q-p;
double t=(w%pq)/(w%v);
return p+v*t;
}
double Square_Triangle(Point p1,Point p2,Point p3){
Vector v=p2-p1,w=p3-p1;
return 0.5*fabs(v%w);
}
struct Segment{
Point p1,p2;
}seg[10];
struct Line{
Point p;
Vector v;
};
bool Line_Inter_Segment(Line l,Segment s){
return dcmp(l.v%(s.p1-l.p))*dcmp(l.v%(s.p2-l.p))<=0;
}
void get_p(Line l,vector<Point>&res){
res.clear();
for(int i=1;i<=4;i++){
if(!Line_Inter_Segment(l,seg[i])) continue;
Point p1=Poi_LineInterLine(l.p,l.v,seg[i].p1,seg[i].p2-seg[i].p1);
int len=(int)res.size();
bool ok=true;
for(int j=0;j<len;j++){
if(p1==res[j]){
ok=false;
break;
}
}
if(ok) res.push_back(p1);
}
}
inline bool comp(const Point a,const Point b){
if(dcmp(a.x-b.x)) return a.x<b.x;
else return a.y<b.y;
}
int main(){
int T=read();
for(int kase=1;kase<=T;kase++){
printf("Case #%d: ",kase);
t1=read(),t2=read(),s1=read(),s2=read(),w=read();
Point p1,p2,p3,p4;
p1=Point(t1,s1);
p2=Point(t2,s1);
p3=Point(t2,s2);
p4=Point(t1,s2);
seg[1].p1=p1,seg[1].p2=p2;
seg[2].p1=p2,seg[2].p2=p3;
seg[3].p1=p3,seg[3].p2=p4;
seg[4].p1=p4,seg[4].p2=p1;
Line l1,l2;
l1.p=Point(0,w);
l1.v=Vector(1,1);
l2.p=Point(0,-w);
l2.v=Vector(1,1);
vector<Point>res;
double ansS=abs(t2-t1)*abs(s2-s1);
int len;
get_p(l1,res);
len=(int)res.size();
if(len>1){
sort(res.begin(),res.end(),comp);
ansS-=Square_Triangle(res[0],p1,p4);
ansS-=Square_Triangle(res[0],res[1],p4);
ansS-=Square_Triangle(res[1],p3,p4);
}
if(p2.y>=p2.x+w) ansS-=abs(t2-t1)*abs(s2-s1);
get_p(l2,res);
len=(int)res.size();
if(len>1){
sort(res.begin(),res.end(),comp);
ansS-=Square_Triangle(res[0],p1,p2);
ansS-=Square_Triangle(res[0],res[1],p2);
ansS-=Square_Triangle(res[1],p2,p3);
}
if(p4.y<=p4.x-w) ansS-=abs(t2-t1)*abs(s2-s1);
ansS/=(abs(t2-t1)*abs(s2-s1));
printf("%.8f\n",ansS);
}
return 0;
}