POJ 3449 (给正方形的对角线两点求另外两点坐标 + 判断线段是否相交)
题目:传送门
题意:给许多多边形, 判断多边形是否相交。
思路:输入输出挺恶心的,得模拟着做。
给正方形的对角线两点,求另外两点坐标可由下列四条式子推导得到:
x1 + x3 = x0 + x2
y1 + y3 = y0 + y2;
y1 - y3 = x0 - x2;
x1 - x3 = y2 - y0;
x1 = ( (x0 + x2) + (y2 - y0) ) / 2
y1 = ( (y0 + y2) + (x0 - x2) ) / 2
x3 = ( (x0 + x2) - (y2 - y0) ) / 2
y3 = ( (y0 + y2) - (x0 - x2) ) / 2
然你矩形的 3 个顶点,让你求第4个,直接算:
x3 = x2 + (x0 - x1)
y3 = y2 + (y0 - y1)
剩下的模拟即可,挺麻烦的。
代码大部分参考了 kuangbin
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <queue> #include <map> #include <vector> #include <set> #include <string> #include <math.h> #define LL long long #define mem(i, j) memset(i, j, sizeof(i)) #define rep(i, j, k) for(int i = j; i <= k; i++) #define dep(i, j, k) for(int i = k; i >= j; i--) #define pb push_back #define make make_pair #define INF INT_MAX #define inf LLONG_MAX #define PI acos(-1) using namespace std; struct Point{ double x, y; Point(double x = 0, double y = 0) : x(x), y(y) { } }; const double eps = 1e-10; int dcmp(double x) { if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; } Point operator + (Point A, Point B) { return Point(A.x + B.x, A.y + B.y); } Point operator - (Point A, Point B) { return Point(A.x - B.x, A.y - B.y); } Point operator * (Point A, double p) { return Point(A.x * p, A.y * p); } Point operator / (Point A, double p) { return Point(A.x / p, A.y / p); } 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; /// 点积 } struct note { char id; int n; Point p[30]; } a[30]; bool cmp(note A, note B) { return A.id < B.id; } bool SPI(Point a1, Point a2, Point b1, Point b2) { /// 判断线段a1a2与线段b1b2是否相交 return max(a1.x,a2.x) >= min(b1.x,b2.x) && max(b1.x,b2.x) >= min(a1.x,a2.x) && max(a1.y,a2.y) >= min(b1.y,b2.y) && max(b1.y,b2.y) >= min(a1.y,a2.y) && dcmp(Cross(b1 - a2, a1 - a2)) * dcmp(Cross(b2 - a2, a1 - a2)) <= 0 && dcmp(Cross(a1 - b2, b1 - b2)) * dcmp(Cross(a2 - b2, b1 - b2)) <= 0; } bool judge(note A, note B) { rep(i, 0, A.n - 1) rep(j, 0, B.n - 1) if(SPI(A.p[i], A.p[(i + 1) % A.n], B.p[j], B.p[(j + 1) % B.n])) return true; return false; } char s[105]; bool vis[105]; int main() { int n; while(scanf("%s", s) == 1) { if(s[0] == '.') break; a[0].id = s[0]; scanf("%s", s); if(strcmp(s,"square")==0) { a[0].n = 4; scanf(" (%lf,%lf)",&a[0].p[0].x,&a[0].p[0].y); scanf(" (%lf,%lf)",&a[0].p[2].x,&a[0].p[2].y); a[0].p[1].x = ((a[0].p[0].x+a[0].p[2].x)+(a[0].p[2].y-a[0].p[0].y))/2; a[0].p[1].y = ((a[0].p[0].y+a[0].p[2].y)+(a[0].p[0].x-a[0].p[2].x))/2; a[0].p[3].x = ((a[0].p[0].x+a[0].p[2].x)-(a[0].p[2].y-a[0].p[0].y))/2; a[0].p[3].y = ((a[0].p[0].y+a[0].p[2].y)-(a[0].p[0].x-a[0].p[2].x))/2; } else if(strcmp(s,"line")==0) { a[0].n = 2; scanf(" (%lf,%lf)",&a[0].p[0].x,&a[0].p[0].y); scanf(" (%lf,%lf)",&a[0].p[1].x,&a[0].p[1].y); } else if(strcmp(s,"triangle")==0) { a[0].n = 3; scanf(" (%lf,%lf)",&a[0].p[0].x,&a[0].p[0].y); scanf(" (%lf,%lf)",&a[0].p[1].x,&a[0].p[1].y); scanf(" (%lf,%lf)",&a[0].p[2].x,&a[0].p[2].y); } else if(strcmp(s,"rectangle")==0) { a[0].n = 4; scanf(" (%lf,%lf)",&a[0].p[0].x,&a[0].p[0].y); scanf(" (%lf,%lf)",&a[0].p[1].x,&a[0].p[1].y); scanf(" (%lf,%lf)",&a[0].p[2].x,&a[0].p[2].y); a[0].p[3].x = a[0].p[2].x + (a[0].p[0].x - a[0].p[1].x); a[0].p[3].y = a[0].p[2].y + (a[0].p[0].y - a[0].p[1].y); } else if(strcmp(s,"polygon")==0) { scanf("%d",&a[0].n); rep(i, 0, a[0].n - 1) { scanf(" (%lf,%lf)",&a[0].p[i].x,&a[0].p[i].y); } } n = 1; while(scanf("%s", s) == 1) { if(s[0] == '-')break; a[n].id = s[0]; scanf("%s", s); if(strcmp(s,"square")==0) { a[n].n = 4; scanf(" (%lf,%lf)",&a[n].p[0].x,&a[n].p[0].y); scanf(" (%lf,%lf)",&a[n].p[2].x,&a[n].p[2].y); a[n].p[1].x = ((a[n].p[0].x+a[n].p[2].x)+(a[n].p[2].y-a[n].p[0].y))/2; a[n].p[1].y = ((a[n].p[0].y+a[n].p[2].y)+(a[n].p[0].x-a[n].p[2].x))/2; a[n].p[3].x = ((a[n].p[0].x+a[n].p[2].x)-(a[n].p[2].y-a[n].p[0].y))/2; a[n].p[3].y = ((a[n].p[0].y+a[n].p[2].y)-(a[n].p[0].x-a[n].p[2].x))/2; } else if(strcmp(s,"line")==0) { a[n].n = 2; scanf(" (%lf,%lf)",&a[n].p[0].x,&a[n].p[0].y); scanf(" (%lf,%lf)",&a[n].p[1].x,&a[n].p[1].y); } else if(strcmp(s,"triangle")==0) { a[n].n = 3; scanf(" (%lf,%lf)",&a[n].p[0].x,&a[n].p[0].y); scanf(" (%lf,%lf)",&a[n].p[1].x,&a[n].p[1].y); scanf(" (%lf,%lf)",&a[n].p[2].x,&a[n].p[2].y); } else if(strcmp(s,"rectangle")==0) { a[n].n = 4; scanf(" (%lf,%lf)",&a[n].p[0].x,&a[n].p[0].y); scanf(" (%lf,%lf)",&a[n].p[1].x,&a[n].p[1].y); scanf(" (%lf,%lf)",&a[n].p[2].x,&a[n].p[2].y); a[n].p[3].x = a[n].p[2].x + (a[n].p[0].x - a[n].p[1].x); a[n].p[3].y = a[n].p[2].y + (a[n].p[0].y - a[n].p[1].y); } else if(strcmp(s,"polygon")==0) { scanf("%d",&a[n].n); rep(i, 0, a[n].n - 1) { scanf(" (%lf,%lf)",&a[n].p[i].x,&a[n].p[i].y); } } n++; } sort(a, a + n, cmp); rep(i, 0, n - 1) { printf("%c ", a[i].id); mem(vis, 0); int cnt = 0; rep(j, 0, n - 1) { if(i == j) continue; if(judge(a[i], a[j])) { cnt++; vis[j] = 1; } } if(cnt == 0) puts("has no intersections"); else if(cnt == 1) { printf("intersects with "); rep(j, 0, n - 1) { if(vis[j]) { printf("%c\n",a[j].id); break; } } } else if(cnt == 2) { printf("intersects with "); rep(j, 0, n - 1) { if(vis[j]) { if(cnt == 2) printf("%c ", a[j].id); if(cnt == 1) printf("and %c\n", a[j].id); cnt--; } } } else { printf("intersects with "); rep(j, 0, n - 1) { if(vis[j]) { if(cnt > 1) printf("%c, ", a[j].id); if(cnt == 1) printf("and %c\n", a[j].id); cnt--; } } } } puts(""); } return 0; }
一步一步,永不停息