URAL 1046 Geometrical dreams 用复平面
2010-07-24 15:53
题目大意:给出一个n个点的多边形,在每一边AiAi+1上有一个等边三角形AiMiAi+1(mi是顶角),现在告诉你每个Mi的坐标和每个顶角的大小,请你算出多边形每个顶点的坐标。 数学 解方程,设第一个点A1是(a,b),放到复平面上就是a+bi,则A2就是 (A1-M1)*(cos(m1)+sin(m1))+M1,我们把它展开,得到A2=X*A1+Y的形式 这样我们依次算下去,就能得到A2,A3。。。最后又回到A1,因此得到了一个形如 X*A1+Y=A1 的方程,把它解出来就得到A1的坐标了。 1046.cpp 我的程序里是全部用pair来表示复数的。 #include<iostream> #include<utility> #include<math.h> using std::cin; using std::cout; using std::endl; using std::pair; using std::fixed; using std::make_pair; typedef pair<double, double> paird; const long double pi=3.1415926535897932384626433; int n; double a[60], m[60][2]; paird xx, yy, ans; paird mul(paird a, paird b) { paird kk; kk.first = a.first * b.first - a.second * b.second; kk.second = a.second * b.first + b.second * a.first; return kk; } paird add(paird a, paird b) { paird kk; kk.first = a.first + b.first; kk.second = a.second + b.second; return kk; } int main() { freopen("1046.in", "r", stdin); freopen("1046.out", "w", stdout); cin >> n; for (int i = 1;i <= n;i++) cin >> m[i][0] >> m[i][1]; for (int i = 1;i <= n;i++) { cin >> a[i]; a[i] = a[i] / 180 * pi; } xx.first = 1; xx.second = 0; yy.first = 0; yy.second = 0; for (int i = 1;i <= n;i++) { xx = mul(xx, make_pair(cos(a[i]), sin(a[i]))); yy = mul(yy, make_pair(cos(a[i]), sin(a[i]))); yy = add(yy, mul(make_pair(-m[i][0], -m[i][1]), make_pair(cos(a[i]), sin(a[i])))); yy = add(yy, make_pair(m[i][0], m[i][1])); } xx.first -= 1; yy.first = - yy.first; yy.second = - yy.second; ans.first = (xx.first * yy.first + xx.second * yy.second) / (xx.first * xx.first + xx.second * xx.second); ans.second = (- xx.second * yy.first + xx.first * yy.second) / (xx.first * xx.first + xx.second * xx.second); cout.precision(2); cout<<fixed; for (int i = 1;i <= n;i++) { cout << ans.first << " " << ans.second << endl; ans = add(ans, make_pair(- m[i][0], -m[i][1])); ans = mul(ans, make_pair(cos(a[i]), sin(a[i]))); ans = add(ans, make_pair(m[i][0], m[i][1])); } } |