Urban Design 计蒜客-43370 计算几何 思维
题意
平面上给出(s)条不会重合的直线,这些直线会把空间划分成很多个区域,任意两个相邻区域是不同的地区。
给出(Q)个询问,每个询问给出两个点问这两个点是否在同一区域。
(读题好难
[1leq s leq 10^4\
1leq T leq 10^3
]
分析
容易发现的规律是只需要判断这两个点组成的线段和多少条直线相交即可。
若相交个数是奇数那么不同区域,否则相同。
判断直线相交可以利用叉乘的性质快速判断。
代码
struct Point {
int x, y;
Point(){}
Point(int _x, int _y) {
x = _x;
y = _y;
}
int operator ^ (const Point& b) {
return x * b.y - y * b.x;
}
Point operator - (const Point& b) {
return Point(x - b.x, y - b.y);
}
};
int cross(Point a, Point b, Point c) {
return (a - c) ^ (b - c);
}
Point p1[10005];
Point p2[10005];
int main() {
int s = readint();
for (int i = 0; i < s; i++) {
int x = readint();
int y = readint();
p1[i] = Point(x, y);
x = readint();
y = readint();
p2[i] = Point(x, y);
}
int n = readint();
for (int i = 0; i < n; i++) {
int num = 0;
int x = readint();
int y = readint();
Point tmp1 = Point(x, y);
x = readint();
y = readint();
Point tmp2 = Point(x, y);
for (int j = 0; j < s; j++) {
if (1ll * cross(p1[j], p2[j], tmp1) * cross(p1[j], p2[j], tmp2) <= 0) num++;
}
if (num & 1) puts("different");
else puts("same");
}
}