码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-04-01 10:14:52      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:

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

判断线段相交模板题。

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

用了“链表”优化之后还是$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 2653】Pick-up sticks 判断线段相交

标签:

原文地址:http://www.cnblogs.com/abclzr/p/5343927.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!