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; }