Urban Design
A new town is being planned, and the designers have some very specific ideas about how things should be laid out. First, they lay out the streets. Each street is perfectly straight and passes completely from one end of the town to the other. These streets divide the town into regions, and each region is to be designated either"residential"or"commercial".The town planners require that any two regions directly across the street from one another must have different designations. On this one particular day, all of the streets have been planned, but none of the regions have been designated. One town planner wishes to purchase two properties, and it is important to him that the properties eventually have different designations. For this problem, the streets can be modeled by lines in the plane that extend forever in both directions and have no width, and properties may be modeled by points. Given the lines and two points, can you decide whether or not they must get different designations,“commercial"or"residential”?
Input
Input begins with an integer S on a single line, giving the number of streets (1≤S≤10000). The next S lines of input each contain four integers x1, y1, x2, and y2, specifying the coordinates of two distinct points (x1, y1) and (x2, y2). The unique line through these two points gives one of the streets. Each coordinate is in the range [0,10000], and no two lines will be identical. That is, the town will have S distinct streets. The next line contains an integer T, the number of pairs of properties to test (1≤T≤1000). This is followed by T lines of input, each containing four integers x3, y3, x4 and y4, representing two distinct points (x3,y3) and (x4,y4), where each point lies within one of the two properties to test. None of these points will lie on any of the streets, nor will both points lie within the same property. Again, each coordinate is in the range [0,10000].
Output
For each of the T pairs of properties to be tested, output either"same"if the properties are guaranteed to receive the same designation or"different"if they are guaranteed to receive different designations.
样例输入1
2
1 1 2 1
1 1 1 2
3
2 0 2 2
2 0 0 3
0 0 2 2
样例输出1
different
same
same
样例输入2
4
1 3 2 4
1 3 2 5
1 3 3 4
7 9 8 8
2
14 7 10 13
1 4 2 3
样例输出2
same
different
实现代码
#include <bits/stdc++.h>
using namespace std;
inline int read() {
char c = getchar();
int x = 0, f = 1;
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e4 + 50;
const double eps = 1e-8;
const double pi = acos(-1.0);
inline double sqr(double x) { return x * x; }
int sgn(double x) {
if (fabs(x) < eps)return 0;
if (x < 0) return -1;
return 1;
}
struct Point {
double x, y;
Point() {}
Point(double xx, double yy) { x = xx, y = yy; }
void input() { scanf("%lf%lf", &x, &y); }
void output() { printf("%f %f\n", x, y); }
bool operator==(Point b) const {
return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
}
bool operator<(Point b) const {
return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : x < b.x;
}
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/(const double &k) const {
return Point(x / k, y / k);
}
//数乘
Point operator*(const double &k) const {
return Point(x * k, y * k);
}
//点乘
double operator*(const Point &b) const {
return x * b.x + y * b.y;
}
//叉乘
double operator^(const Point &b) const {
return x * b.y - y * b.x;
}
//和原点的距离
double len() { return hypot(x, y); }
//长度的平方
double len2() { return x * x + y * y; }
//两点距离
inline double distance(Point p) {
return hypot(x - p.x, y - p.y);
}
//与a、b两点的夹角
double rad(Point a, Point b) {
Point p = *this;
return fabs(atan2(fabs((a - p) ^ (b - p)), (a - p) * (b - p)));
}
};
struct Line {
Point s, e;
Line() {}
Line(Point ss, Point ee) { s = ss, e = ee; }
bool operator==(Line v) {
return (s == v.s) && (e == v.e);
}
//根据点和倾斜角确定直线,0<=angle<pi
Line(Point p, double angle) {
s = p;
if (sgn(angle - pi / 2) == 0) e = (s + Point(0, 1));
else e = (s + Point(1, tan(angle)));
}
//ax+by+c=0
Line(double a, double b, double c) {
if (sgn(a) == 0) {
s = Point(0, -c / b);
e = Point(1, -c / b);
} else if (sgn(b) == 0) {
s = Point(-c / a, 0);
e = Point(-c / a, 1);
} else {
s = Point(0, -c / b);
e = Point(1, (-c - a) / b);
}
}
double length() {
return s.distance(e);
}
//返回直线倾斜角0<=angle<pi
double angle() {
double k = atan2(e.y - s.y, e.x - s.x);
if (sgn(k) < 0) k += pi;
if (sgn(k - pi) == 0) k -= pi;
return k;
}
//点和直线关系 1左 2右 3线上
int relation(Point p) {
int c = sgn((p - s) ^ (e - s));
if (c < 0) return 1;
else if (c > 0) return 2;
else return 3;
}
//判点在线段上
bool pointonseg(Point p) {
return sgn((p - s) ^ (e - s)) == 0 && sgn((p - s) * (p - e)) <= 0;
}
//两向量平行(对应直线平行或重合)
bool parallel(Line v) {
return sgn((e - s) ^ (v.e - v.s)) == 0;
}
//线段相交判断 2规范相交 1非规范 0不相交
int segcrossseg(Line v) {
int d1 = sgn((e - s) ^ (v.s - s));
int d2 = sgn((e - s) ^ (v.e - s));
int d3 = sgn((v.e - v.s) ^ (s - v.s));
int d4 = sgn((v.e - v.s) ^ (e - v.s));
if ((d1 ^ d2) == -2 && (d3 ^ d4) == -2) return 2;
return (d1 == 0 && sgn((v.s - s) * (v.s - e)) <= 0) ||
(d2 == 0 && sgn((v.e - s) * (v.e - e)) <= 0) ||
(d3 == 0 && sgn((s - v.s) * (s - v.e)) <= 0) ||
(d4 == 0 && sgn((e - v.s) * (e - v.e)) <= 0);
}
//直线和线段相交判断 2规范相交 1非规范 0不相交
//*this:line v:seg
int linecrossseg(Line v) {
int d1 = sgn((e - s) ^ (v.s - s));
int d2 = sgn((e - s) ^ (v.e - s));
if ((d1 ^ d2) == -2) return 2;
return (d1 == 0 || d2 == 0);
}
//两直线关系 0平行 1重合 2相交
int linecrossline(Line v) {
if ((*this).parallel(v)) return v.relation(s) == 3;
return 2;
}
//求两直线交点,判过不平行重合嗷
Point crosspoint(Line v) {
double a1 = (v.e - v.s) ^(s - v.s);
double a2 = (v.e - v.s) ^(e - v.s);
return Point((s.x * a2 - e.x * a1) / (a2 - a1), (s.y * a2 - e.y * a1) / (a2 - a1));
}
//点到直线距离
double dispointtoline(Point p) {
return fabs((p - s) ^ (e - s)) / length();
}
//点到线段距离
double dispointtoseg(Point p) {
if (sgn((p - s) * (e - s)) < 0 || sgn((p - e) * (s - e)) < 0)
return min(p.distance(s), p.distance(e));
return dispointtoline(p);
}
//两平行线段距离
double dissegtoseg(Line v) {
return min(min(dispointtoseg(v.s), dispointtoseg(v.e)), min(v.dispointtoseg(s), v.dispointtoseg(e)));
}
//p在直线上的投影
Point lineprog(Point p) {
return s + (((e - s) * ((e - s) * (p - s))) / ((e - s).len2()));
}
//p关于直线的对称点
Point symmetrypoint(Point p) {
Point q = lineprog(p);
return Point(2 * q.x - p.x, 2 * q.y - p.y);
}
};
struct circle {
Point p;
double r;
};
Line l[maxn], se[maxn];
int main() {
int s = read();
for (int i = 0; i < s; i++) {
l[i].s.input();
l[i].e.input();
}
int t = read();
for (int i = 0; i < t; i++) {
se[i].s.input();
se[i].e.input();
int cnt = 0;
for (int j = 0; j < s; j++) {
if (l[j].linecrossseg(se[i]) == 2) cnt++;
}
if (cnt & 1) puts("different");
else puts("same");
}
return 0;
}