Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1467 Accepted Submission(s): 642
Special Judge
Problem Description
Noting is more interesting than rotation!
Your little sister likes to rotate things. To put it easier to analyze, your sister makes n rotations. In the i-th time, she makes everything in the plane rotate counter-clockwisely around a point ai by a radian of pi.
Now she promises that the total effect of her rotations is a single rotation around a point A by radian P (this means the sum of pi is not a multiplier of 2π).
Of course, you should be able to figure out what is A and P :).
Input
The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains an integer n denoting the number of the rotations. Then n lines follows, each containing 3 real numbers x, y and p, which means rotating around point (x, y) counter-clockwisely by a radian of p.
We promise that the sum of all p's is differed at least 0.1 from the nearest multiplier of 2π.
T<=100. 1<=n<=10. 0<=x, y<=100. 0<=p<=2π.
Output
For each test case, print 3 real numbers x, y, p, indicating that the overall rotation is around (x, y) counter-clockwisely by a radian of p. Note that you should print p where 0<=p<2π.
Your answer will be considered correct if and only if for x, y and p, the absolute error is no larger than 1e-5.
Sample Input
1 3 0 0 1 1 1 1 2 2 1
Sample Output
1.8088715944 0.1911284056 3.0000000000
Source
2014 ACM/ICPC Asia Regional Anshan Online
思路:任意选择两个点(我选的A(0,0)B(1,1)),然后按照输入数据对这两个点进行旋转,最终得到点AA 点BB,整个过程等效于绕线段A AA 线段B BB 垂直平分线的交点 旋转sum(anglei)对2pi取余弧度
用的kuangbin的模板,话说这个模板容易被卡精度啊,网上的其它题解用的都是double,我必须用long double才能过,因为这个wa了十几发
#include
#include
#include
using namespace std;
typedef long double LD;
const double pi = acos(-1.0);
const double eps = 1e-8;
int sgn(LD x)
{
if(fabs(x) < eps) return 0;
if(x < 0) return -1;
else return 1;
}
struct Point
{
LD x, y;
Point(){}
Point(double _x, double _y)
{
x = _x;
y = _y;
}
void input()
{
//scanf("%lf %lf", &x, &y);
cin >> x >> y;
}
Point operator - (const Point &b) const
{
return Point(x - b.x, y - b.y);
}
Point operator + (const Point &b) const
{
return Point(x + b.x, y + b.y);
}
//绕P逆时针旋转angle
Point Rotate(Point p, LD angle)
{
Point v = (*this) - p;
LD c = cos(angle), s = sin(angle);
return Point(p.x + v.x * c - v.y * s, p.y + v.x * s + v.y *c);
}
Point operator / (const LD &k) const
{
return Point(x / k, y / k);
}
LD operator ^(const Point &b) const
{
return x * b.y - y * b.x;
}
};
struct Line
{
Point s, e;
Line(){}
Line(Point _s, Point _e)
{
s = _s;
e = _e;
}
//求两直线的交点
Point crosspoint(Line v)
{
LD a1 = (v.e - v.s) ^ (s - v.s);
LD a2 = (v.e - v.s) ^ (e - v.s);
return Point((s.x * a2 - e.x * a1) / (a2 - a1),
(s.y * a2 - e.y * a1) / (a2 - a1));
}
//求线段的中垂线
Line getMidLine()
{
Point mid = (s + e);
mid.x /= 2.0;
mid.y /= 2.0;
Point tp = e - s;
return Line(mid, mid + Point(-tp.y, tp.x));
}
};
int main(void)
{
int T;
scanf("%d", &T);
while (T--) {
int n;
scanf("%d", &n);
Point A = Point(1, 1);
Point B = Point(0, 0);
Point C;
LD angle;
LD ans = 0;
while (n--) {
C.input();
cin >> angle;
ans += angle;
if (ans > 2 * pi) ans -= 2 * pi;
A = A.Rotate(C, angle);
B = B.Rotate(C, angle);
}
Point AA = Point(1, 1);
Point BB = Point(0, 0);
Line l1 = Line(AA,A).getMidLine();
Line l2 = Line(BB,B).getMidLine();
C = l2.crosspoint(l1);
cout << C.x << " " << C.y << " " << ans << endl;
}
return 0;
}