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


    一定要注意位运算的优先级!!!我被这个卡了好久

    判断线段相交模板题。

    叉积,点积,规范相交,非规范相交的简单模板

    用了“链表”优化之后还是$O(n^2)$的暴力,可是为什么能过$10^5$的数据?

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 100005
    using namespace std;
    struct Point {
    	double x, y;
    	Point(double _x = 0, double _y = 0) : x(_x), y(_y) {}
    };
    inline int dcmp(double x) {
    	return fabs(x) < 1e-6 ? 0 : (x < 0 ? -1 : 1);
    }
    Point operator - (Point a, Point b) {
    	return Point(a.x - b.x, a.y - b.y);
    }
    bool operator == (Point a, Point b) {
    	return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
    }
    double Cross(Point a, Point b) {
    	return a.x * b.y - a.y * b.x;
    }
    double Dot(Point a, Point b) {
    	return a.x * b.x + a.y * b.y;
    }
    bool jiao(Point d1, Point d2, Point d3, Point d4) {
    	return (dcmp(Cross(d4 - d3, d1 - d3)) ^ dcmp(Cross(d4 - d3, d2 - d3))) == -2 &&
    			(dcmp(Cross(d2 - d1, d3 - d1)) ^ dcmp(Cross(d2 - d1, d4 - d1))) == -2;
    }
    int bjiao(Point d1, Point d2, Point d3) {
    	if (d1 == d2 || d1 == d3)
    		return 1;
    	if (dcmp(Cross(d2 - d1, d3 - d1)) == 0 && dcmp(Dot(d2 - d1, d3 - d1)) == -1)
    		return 1;
    	return 0;
    }
    Point d[N][2];
    int n, next[N], ans[N], cnt;
    inline bool pd(int now, int up) {
    	if (bjiao(d[now][0], d[up][0], d[up][1]) ||
    		bjiao(d[now][1], d[up][0], d[up][1]) ||
    		bjiao(d[up][0], d[now][0], d[now][1]) ||
    		bjiao(d[up][1], d[now][0], d[now][1]))
    		return 1;
    	return jiao(d[now][0], d[now][1], d[up][0], d[up][1]);
    }
    inline void mktb(int up) {
    	for(int now = next[0], pre = 0; now != up; now = next[now]) {
    		if (pd(now, up))
    			next[pre] = next[now];
    		else
    			pre = now;
    	}
    }
    int main() {
    	scanf("%d", &n);
    	while (n) {
    		for(int i = 0; i <= n; ++i)
    			next[i] = i + 1;
    		for(int i = 1; i <= n; ++i) {
    			scanf("%lf%lf%lf%lf", &d[i][0].x, &d[i][0].y, &d[i][1].x, &d[i][1].y);
    			mktb(i);
    		}
    		cnt = 0;
    		for(int now = next[0]; now != n + 1; now = next[now])
    			ans[++cnt] = now;
    		printf("Top sticks:");
    		for(int i = 1; i < cnt; ++i)
    			printf("% d,", ans[i]);
    		printf(" %d.
    ", ans[cnt]);
    		scanf("%d", &n);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Android 使用MediaPlayer 播放 视频
    Android加载asset的db
    MAC SVN 基本设置 终端命令
    AFNetWork 简单实用demo
    IntelliJ IDEA导出Java 可执行Jar包
    Xcode快速排错
    Listview多tab上滑悬浮
    N最短路径分词
    进程监控工具supervisor
    nginx配置指南
  • 原文地址:https://www.cnblogs.com/abclzr/p/5343927.html
Copyright © 2020-2023  润新知