一道非常"简单"的计算几何题。。。
题意:给你两个三角形和一个四边形,问你能否用这两个三角形拼成这个四边形
首先。。。四边形可能是凹四边形。。。需要判断一下。。。这个比较简单直接分成两部分即可。。。
然后。。。四边形可能会退化成三角形。。。那就需要两个三角形拼起来的时候某两个角之和为180°
最后暴力一下如何划分四边形即可。。。
写的真是开心,还好一遍A了QAQ
1 /************************************************************** 2 Problem: 2494 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:8 ms 7 Memory:820 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 14 using namespace std; 15 typedef double lf; 16 17 template <class T> inline T sqr(const T &x) { 18 return x * x; 19 } 20 21 template <class T> inline int sgn(const T &x) { 22 const T eps = 1e-8; 23 if (fabs(x) < eps) return 0; 24 return x < 0 ? -1 : 1; 25 } 26 27 struct point { 28 lf x, y; 29 point() {} 30 point(lf _x, lf _y) : x(_x), y(_y) {} 31 32 inline point operator + (const point &p) const { 33 return point(x + p.x, y + p.y); 34 } 35 inline point operator - (const point &p) const { 36 return point(x - p.x, y - p.y); 37 } 38 inline lf operator * (const point &p) const { 39 return x * p.y - y * p.x; 40 } 41 inline point operator * (const lf &d) const { 42 return point(x * d, y * d); 43 } 44 inline void get() { 45 scanf("%lf%lf", &x, &y); 46 } 47 friend inline lf dis2(const point &p) { 48 return sqr(p.x) + sqr(p.y); 49 } 50 friend inline lf dis(const point &p) { 51 return sqrt(dis2(p)); 52 } 53 } t[2][6], p[8]; 54 55 inline bool check(const point &a, const point &b, const point &c, const int &p) { 56 static lf T1[3], T2[3]; 57 static int i; 58 T1[0] = dis(a - b), T1[1] = dis(b - c), T1[2] = dis(c - a); 59 for (i = 0; i < 3; ++i) 60 T2[i] = dis(t[p][i] - t[p][i + 1]); 61 sort(T1, T1 + 3), sort(T2, T2 + 3); 62 for (i = 0; i < 3; ++i) 63 if (sgn(T1[i] - T2[i]) != 0) return 0; 64 return 1; 65 } 66 67 inline point get_cross(const point &a, const point &b, const point &c, const point &d) { 68 static lf rate; 69 rate = 1 / (1 - ((d - c) * (b - c)) / ((d - c) * (a - c))); 70 return (b - a) * rate + a; 71 } 72 73 int main() { 74 int T, icase, i, j, f; 75 lf di[6], d1; 76 point p1, a, b, c, d, e; 77 scanf("%d", &T); 78 for (icase = 1; icase <= T; ++icase) { 79 f = 0; 80 for (i = 0; i < 3; ++i) t[0][i].get(), t[0][i + 3] = t[0][i]; 81 for (i = 0; i < 3; ++i) t[1][i].get(), t[1][i + 3] = t[1][i]; 82 for (i = 0; i < 4; ++i) p[i].get(), p[i + 4] = p[i]; 83 84 for (i = 0; i < 3; ++i) 85 di[i] = dis(t[0][i] - t[0][i + 1]), di[i + 3] = dis(t[1][i] - t[1][i + 1]); 86 if (((p[2] - p[0]) * (p[1] - p[0])) * ((p[2] - p[0]) * (p[3] - p[0])) < 0) { 87 if (check(p[0], p[1], p[2], 0) && check(p[0], p[2], p[3], 1)) f = 1; 88 if (check(p[0], p[1], p[2], 1) && check(p[0], p[2], p[3], 0)) f = 1; 89 } 90 if (((p[3] - p[1]) * (p[0] - p[1])) * ((p[3] - p[1]) * (p[2] - p[1])) < 0) { 91 if (check(p[1], p[3], p[0], 0) && check(p[1], p[3], p[2], 1)) f = 1; 92 if (check(p[1], p[3], p[0], 1) && check(p[1], p[3], p[2], 0)) f = 1; 93 } 94 95 for (i = 0; i < 4; ++i) { 96 a = p[i], b = p[i + 1], c = p[i + 2], d = p[i + 3]; 97 if (((b - a) * (c - a)) * ((b - a) * (d - a)) < 0) { 98 e = get_cross(a, b, c, d); 99 if (check(a, d, e, 0) && check(b, c, e, 1)) f = 1; 100 if (check(a, d, e, 1) && check(b, c, e, 0)) f = 1; 101 } 102 } 103 for (i = 0; i < 4; ++i) if (sgn((p[i + 1] - p[i]) * (p[i + 2] - p[i])) == 0) { 104 d1 = dis(p[i + 2] - p[i]); 105 for (j = 0; j < 6; ++j) if (d1 >= di[j]) { 106 p1 = p[i + 2] - p[i]; 107 p1 = p1 * (di[j] / d1) + p[i]; 108 if (check(p[i + 3], p[i], p1, 0) && check(p[i + 3], p[i + 2], p1, 1)) f = 1; 109 if (check(p[i + 3], p[i], p1, 1) && check(p[i + 3], p[i + 2], p1, 0)) f = 1; 110 } 111 } 112 printf("Case #%d: %s ", icase, f ? "Yes" : "No"); 113 } 114 return 0; 115 }