Posted on 2007-02-17 02:40
oyjpart 閱讀(1205)
評論(0) 編輯 收藏 引用 所屬分類:
ACM/ICPC或其他比賽
題目大意是給出第一條向量和一個公比k 以及一個旋轉角度A
然后沿第一條向量左旋A角度 前進k*第一條向量的距離 得到第二條向量
如此下去 最終停在一個點上
題目雖然結果只需要輸出3為 但是想從精度上打主意進行近似模擬是不行的
正確的解法是吧這個坐標平面看成一個復數平面
設向量V : x + yi
則左旋A角度之后的向量應該是xcosA - ysinA + (ycosA + xsinA)i
(我是化成極坐標得出來的) 相當于乘上cosA+sinAi
而距離變成k倍實際上就是乘上k
那么無窮盡的旋轉 其實就是首相為x+yi, 公比為kcosA+ksinAi的等比數列 其和為
?????????? x+yi
————————
(1 - kcosA) - ksinAi
復數的除法可以轉化成乘法(兩邊同時成一共軛復數即可) 這樣就能夠解決問題了
Solution
//by oyjpArt
#include <stdio.h>
#include <math.h>
const double EPS = 10e-6;
int main() {
?double a, b, r, x, y, A, k, c, d;
?while(scanf("%lf %lf %lf %lf", &x, &y, &A, &k) != EOF) {
??A = A * acos(-1)/180.0;
??a = 1.0 - k * cos(A);
??b = -k * sin(A);
??c = x * a + y * b;
??d = y * a - x * b;
??r = a * a + b * b;
??printf("(%.3lf,%.3lf)\n", c/r+EPS, d/r+EPS);
?}
?return 0;
}
//BTW: #include <complex> & use overloaded / could make division easier.
Like this:
#include <stdio.h>
#include <math.h>
#include <complex>
using namespace std;
typedef complex<double> Comp;
const double EPS = 10e-6;
int main() {
?double x, y, A, k;
?while(scanf("%lf %lf %lf %lf", &x, &y, &A, &k) != EOF) {
??A = A * acos(-1)/180.0;
??Comp a(x, y);
??Comp b(1-k*cos(A), -k*sin(A));
??Comp c = a/b;
??printf("(%.3lf,%.3lf)\n", c.real()+EPS, c.imag()+EPS);
?}
?return 0;
}
?