【线段相交】 POJ 2653 Pick-up sticks

来源:互联网 发布:淘宝上鞋子哪个店好 编辑:程序博客网 时间:2024/05/16 08:40

线段相交水题,维护一个队列就行。。。

#include <iostream>#include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits>#include <cstdlib>#include <cmath>#include <time.h>#define maxn 1000005#define maxm 2000005#define eps 1e-10#define mod 1000000007#define INF 1e9#define lowbit(x) (x&(-x))#define mp make_pair#define ls o<<1#define rs o<<1 | 1#define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R typedef long long LL;typedef unsigned long long ULL;//typedef int LL;using namespace std;int dcmp(double d){if(fabs(d) < eps) return 0;else return d > eps ? 1 : -1;}struct point{double x, y;point(double x = 0, double y = 0) : x(x), y(y) {}bool operator < (const point& b) const {if(dcmp(x - b.x) == 0) return dcmp(y - b.y) < 0;else return x < b.x;}bool operator == (const point& b) const {return dcmp(x - b.x) == 0 && dcmp(y - b.y) == 0;}point operator + (const point& b) const {return point(x + b.x, y + b.y);}point operator - (const point& b) const {return point(x - b.x, y - b.y);}point operator * (double b) const {return point(x * b, y * b);}point operator / (double b) const {return point(x / b, y / b);}void out(void){printf("x = %.3f y = %.3f\n", x, y);}};typedef point vec;//点积double dot(vec a, vec b){return a.x * b.x + a.y * b.y;}//向量的长度double length(vec a){return sqrt(dot(a, a));}//两个向量的夹角double angle(vec a, vec b){return acos(dot(a, b) / length(a) / length(b));}//向量叉积double cross(vec a, vec b){return a.x * b.y - a.y * b.x;}//向量旋转,rad是弧度vec rotate(vec a, double rad){return vec(a.x * cos(rad) - a.y * sin(rad), a.x * sin(rad) + a.y * cos(rad));}//求法向量,顺时针旋转90度vec normal(vec a){double L = length(a);return vec(-a.y / L, a.x / L);}//求两条直线的交点,调用前要确保两条直线相交point intersection(point a, vec v1, point b, vec v2){vec u = a - b;double t = cross(v2, u) / cross(v1, v2);return a + v1 * t;}//求点到直线的距离double distoline(point p, point a, point b){vec v1 = b - a, v2 = p - a;return fabs(cross(v1, v2)) / length(v1);//如果不取绝对值得到的是有向距离}//求点到线段的距离double distosegment(point p, point a, point b){if(a == b) return length(p - a);vec v1 = b - a, v2 = p - a, v3 = p - b;if(dcmp(dot(v1, v2)) < 0) return length(v2);else if(dcmp(dot(v1, v3)) > 0) return length(v3);else return fabs(cross(v1, v2)) / length(v1);}//点在线段上的投影point projection(point p, point a, point b){vec v = b - a;return a + v * (dot(v, p - a) / dot(v, v));}//已经知道p在ab直线上,判断p和线段ab的关系//p在不在线段上返回1,在线段端点返回0,在线段上返回-1int onseg(point p, point a, point b){if(fabs(a.x - b.x) > fabs(a.y - b.y)) return dcmp(p.x - a.x) * dcmp(p.x - b.x);else return dcmp(p.y - a.y) * dcmp(p.y - b.y);}//线段相交,规范相交返回1,不规范相交返回2,不相交返回0bool segtoseg(point a1, point b1, point a2, point b2){int d1 = dcmp(cross(b1 - a1, a2 - a1));int d2 = dcmp(cross(b1 - a1, b2 - a1));int d3 = dcmp(cross(b2 - a2, a1 - a2));int d4 = dcmp(cross(b2 - a2, b1 - a2));if(d1 * d2 < 0 && d3 * d4 < 0) return 1;if(d1 == 0 && onseg(a2, a1, b1) <= 0) return 2;if(d2 == 0 && onseg(b2, a1, b1) <= 0) return 2;if(d3 == 0 && onseg(a1, a2, b2) <= 0) return 2;if(d4 == 0 && onseg(b1, a2, b2) <= 0) return 2;return 0;}struct segment{point a, b;}s[maxn];int q[2][1005];int n;void work(void){int now = 0, cnt = 0, next;for(int i = 1; i <= n; i++) {scanf("%lf%lf%lf%lf", &s[i].a.x, &s[i].a.y, &s[i].b.x, &s[i].b.y);next = now ^ 1;int t = 0;for(int j = 1; j <= cnt; j++)if(segtoseg(s[q[now][j]].a, s[q[now][j]].b, s[i].a, s[i].b) == 0)q[next][++t] = q[now][j];q[next][++t] = i;now = next, cnt = t;}printf("Top sticks: ");for(int i = 1; i <= cnt; i++) printf("%d%s", q[now][i], i != cnt ? ", " : ".\n");}int main(void){while(scanf("%d", &n), n != 0) work();return 0;}


0 0