SOJ 1059. Exocenter of a Trian

题目大意:给定一个三角形ABC,求三角形的Exocenter。Exocenter定义:对三角形ABC三边作正方形,得到正方形ADEB,BJHC,CFGA,连接DG,EJ,FH,取DG、EJ、FH的中点L、M、N,直线LA、BM、CN的交点即为Exocenter.

解题思路:求出直线LA和MB,用高斯消元法求交点O。先用垂直条件、等长条件和钝角条件求D、G、E、J的坐标,再求L、M的坐标。

注意:浮点误差,两垂直直线和三种情况。

代码如下:

  1 #include <cstdio>
  2 #include <cmath>
  3 #include <utility>
  4 #include <climits>
  5 #include <vector>
  6 using namespace std;
  7 
  8 //typedef pair<double, double> Cor;
  9 
 10 struct Cor{
 11     double x;
 12     double y;
 13     Cor(double x_ = 0, double y_ = 0) : x(x_), y(y_) {}
 14     Cor operator-(const Cor &other) const {
 15         return Cor(x - other.x, y - other.y);
 16     }
 17 
 18     Cor operator+(const Cor &other) const {
 19         return Cor(x + other.x, y + other.y);
 20     }
 21     Cor operator/(const double &num) const {
 22         return Cor(x / num, y / num);
 23     }
 24     static Cor midCor(const Cor &cor1, const Cor &cor2) {
 25         return (cor1 + cor2) / 2;
 26     }
 27 };
 28 
 29 const double error_range = 0.0000001;
 30 bool doubleEqual(const double & a, const double &b) {
 31     return fabs(a - b) <= error_range;
 32 }
 33 
 34 bool doubleLarger(const double &a, const double &b) {
 35     return a - b > error_range;
 36 }
 37 
 38 bool doubleSmaller(const double &a, const double &b) {
 39     return b - a > error_range;
 40 }
 41 
 42 double dot(const Cor &A, const Cor &B) {
 43     return A.x * B.x + A.y * B.y;
 44 }
 45 
 46 Cor getExtrianglePoint(const Cor &B, const Cor &A, const Cor &C) {
 47     Cor one, two;
 48     // 如果原直线平行于x轴
 49     if (A.y == B.y) {
 50         one.x = A.x;
 51         one.y = A.y + fabs(B.x - A.x);
 52         two.x = A.x;
 53         two.y = A.y - fabs(B.x - A.x);
 54     } else if (A.x == B.x) {
 55         one.y = A.y;
 56         one.x = A.x + fabs(B.y - A.y);
 57         two.y = A.y;
 58         two.x = A.x - fabs(B.y - A.y);
 59     } else {
 60         one.x = A.x + fabs(B.y - A.y);
 61         one.y = A.y - (B.x - A.x) * (one.x - A.x) / (B.y - A.y);
 62         two.x = A.x - fabs(B.y - A.y);
 63         two.y = A.y - (B.x - A.x) * (two.x - A.x) / (B.y - A.y);
 64     }
 65 
 66     if (doubleSmaller(dot(one - A, C - A), 0 )) {
 67         return one;
 68     } else if (doubleSmaller(dot(two - A, C - A), 0)) {
 69         return two;
 70     } else {
 71         printf("error\n");
 72         return Cor();
 73     }
 74 
 75 }
 76 
 77 vector<double> Gauss(double (*matrix)[3], const int &n) {
 78     vector<int> select(n - 1);
 79     vector<bool> visited(n - 1, false);
 80     bool notSingle = false;
 81     for (int i = 0; i < n - 1; ++i) {
 82         int maximum_num;
 83         double maximum = 0;
 84         for (int j = 0; j < n - 1; ++j) {
 85             if (!visited[j] && doubleLarger(fabs(matrix[j][i]), fabs(maximum))) {
 86                 maximum_num = j;
 87                 maximum = matrix[j][i];
 88             }
 89         }
 90         if (doubleEqual(maximum, 0)) {
 91             notSingle = true;
 92             break;
 93         }
 94         visited[maximum_num] = true;
 95         select[i] = maximum_num;
 96         for (int j = 0; j < n - 1; ++j) {
 97             if (j == maximum_num) continue;
 98             if (doubleEqual(matrix[j][i], 0)) continue;
 99             double coefficient = -1 * matrix[j][i] / maximum;
100             for (int k = i; k < n; ++k) {
101                 matrix[j][k] = matrix[maximum_num][k] * coefficient + matrix[j][k];
102             }
103         }
104     }
105     vector<double> ans;
106     if (notSingle) return ans;
107     for (int i = 0; i < select.size(); ++i) {
108         ans.push_back(matrix[select[i]][n - 1] / matrix[select[i]][i]);
109     }
110     return ans;
111 }
112 
113 double GM[2][3];
114 
115 
116 
117 int main() {
118     int n;
119     Cor A, B, C;
120     scanf("%d", &n);
121     while (n--) {
122         scanf("%lf%lf%lf%lf%lf%lf", &A.x, &A.y, &B.x, &B.y, &C.x, &C.y);
123         Cor D = getExtrianglePoint(B, A, C);
124         Cor G = getExtrianglePoint(C, A, B);
125         Cor L = (D + G) / 2;
126         Cor E = getExtrianglePoint(A, B, C);
127         Cor J = getExtrianglePoint(C, B, A);
128         Cor M = (E + J) / 2;
129         
130         if (doubleEqual(L.x, A.x)) {
131             GM[0][0] = 1;
132             GM[0][1] = 0;
133             GM[0][2] = L.x;
134         } else {
135             GM[0][0] = (L.y - A.y) / (L.x - A.x);
136             GM[0][1] = -1;
137             GM[0][2] = (L.y - A.y) / (L.x - A.x) * A.x - A.y;
138         }
139 
140         if (doubleEqual(M.x, B.x)) {
141             GM[1][0] = 1;
142             GM[1][1] = 0;
143             GM[1][2] = M.x;
144         } else {
145             GM[1][0] = (M.y - B.y) / (M.x - B.x);
146             GM[1][1] = -1;
147             GM[1][2] = (M.y - B.y) / (M.x - B.x) * B.x - B.y;
148         }
149 
150         vector<double> ans = Gauss(GM, 3);
151         for (int i = 0; i < ans.size(); ++i) {
152             printf("%.4lf%c", doubleEqual(ans[i], 0) ? 0 : ans[i], i == ans.size() - 1 ? '\n' : ' ');
153         }
154     }
155     return 0;
156 }

 

posted @ 2015-11-17 21:10  MchCyLh  阅读(158)  评论(0编辑  收藏  举报