lightoj 1320

输入:

给组数;

给边数N,给X最大,给Y最大,

给N条边,X1Y1,X2Y2;

问区域内有几个块。

思路清晰,对于每条边,有自己的影响,影响就是和之前的边有多少交点。有一个交点加一块,自身是一块。

但是有个技巧,就是浮点数的点,怎么存;

发现直线相交的交点是

X=(l2.b*l1.c - l1.b*l2.c)/det;

Y=(l1.a*l2.c - l2.a*l1.c)/det;

所以存的时候直接存个PAIR表示点对,注意GCD,否则会重点;

由此而来的就是对于边界的比较。很机智。

#include<bits/stdc++.h>
using namespace std;

int n,L,W;

struct line{
    int a,b,c;
    line(){}
    line(int x1,int y1,int x2, int y2){
            a = y1 - y2;
            b = x2 - x1;
            c = a*x1 + b*y1;
    }
};

struct point{
    int x,y;
    point(){}
    point(int a): x(a),y(1){}
    point(int a, int b){
        x = a/__gcd(a,b);
        y = b/__gcd(a,b);
    }
    bool operator < (const point &o) const{
        return x*o.y < y*o.x;
    }

};

bool intersection(line l1,line l2, point &x,point &y){
    int det = l1.a*l2.b - l2.a*l1.b;
    if(det == 0) // lines are parallel
        return false;
    x = point(l2.b*l1.c - l1.b*l2.c,det);
    y = point(l1.a*l2.c - l2.a*l1.c,det);
    return true;
}



vector<line> lines;

int solve(){
    point minx(0);
    point miny(0);
    point maxx(L);
    point maxy(W);
    int ans = 1;
    for(int i = 0; i< n; ++i){
        set<pair<point,point> > points;
        for(int j = 0; j< i; ++j){
            point x,y;
            if(intersection(lines[i],lines[j],x,y)){
                if(minx < x and x < maxx and miny < y and y < maxy)
                    points.insert(make_pair(x,y));
            }
        }
        ans += points.size() + 1;
    }
    return ans;
}

int main(){
    int tc;cin>>tc;
    int a,b,c,d;
    for(int tid = 1; tid <= tc; ++tid){
        cin>>n>>L>>W;
        lines.clear();
        for(int i = 0 ; i< n; ++i){
            cin>>a>>b>>c>>d;
            lines.push_back(line(a,b,c,d));
        }
        printf("Case %d: %d\n",tid,solve());

    }

    return 0;
}

 

posted on 2016-07-05 22:00  very_czy  阅读(141)  评论(0编辑  收藏  举报

导航