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

Posted abclzr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2653Pick-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.\n", ans[cnt]);
		scanf("%d", &n);
	}
	return 0;
}

 

以上是关于POJ 2653Pick-up sticks 判断线段相交的主要内容,如果未能解决你的问题,请参考以下文章

POJ2653 Pick-up sticks 判断线段相交

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

POJ 2653 Pick-up sticks

POJ 2653 Pick-up sticks(线段相交)

POJ 2653 Pick-up sticks (线段相交)

[POJ 2653]Pick-up sticks