UVA 11722(概率+几何)

http://uva.onlinejudge.org/external/117/11722.pdf

Problem

Solution

求概率方法就是lrj的方法。怎么求面积比,又不要分太多情况讨论呢?首先,线段与直线相交怎么判断,直线与直线求交点怎么求,然后,怎么把四边形的面积转换为三个三角形面积相加,怎么判断两条直线之间没有夹四边形的情况?解决这些情况就行了,基本模板大白书都有。

My code

//Hello. I'm Peter.
#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;
}

你可能感兴趣的:(几何,概率)