http://acm.hdu.edu.cn/showproblem.php?pid=4998

这道题,在比赛的时候看了很久,才明白题目的大意。都怪自己不好好学习英语。后来经过队友翻译才懂是什么意思。

题目大意:二维平面内的物品,把它们绕给定的n个点,逆时针旋转。 现在求通过一个A点,逆时针旋转角度P就能完成这个操作。

问:这个点A的坐标,P的角度。

解题思路:随意找个点t1,绕着n个点旋转得到t2。点A一定在线段t1t2的垂直平分线上。再找一点t3,绕n个点旋转得到t4。

线段t1t2的垂直平分线和线段t3t4的垂直平分线相交一点,这点就是A点。证明过程就不写了,可以画图看看。

旋转的角度是向量At1和向量At2的夹角Θ,或是2∏-Θ

 #include<cstdio>
#include<cmath>
#include<iostream>
using namespace std; struct Point{
double x, y; Point(double x = , double y = ): x(x), y(y){}
}; typedef Point Vector; const double eps = 1e-; int dcmp(double x){
if(fabs(x) < eps)
return ;
return x < ? - : ;
} bool operator == (Point A, Point B){
return dcmp(A.x - B.x) == && dcmp(A.y - B.y) == ;
} Vector operator + (Vector A, Vector B){
return Vector(A.x + B.x, A.y + B.y);
} Vector operator - (Vector A, Vector B){
return Vector(A.x - B.x, A.y - B.y);
} Vector operator * (Vector A, double p){
return Vector(A.x * p, A.y * p);
} Vector operator / (Vector A, double p){
return Vector(A.x / p, A.y / p);
} double dot(Vector A, Vector B){//点乘
return A.x * B.x + A.y * B.y;
} double length(Vector A){//向量的模
return sqrt(dot(A, A));
} double angle(Vector A, Vector B){//两个向量的夹角
return acos(dot(A, B) / length(A) / length(B));
} Vector rotate(Vector A, double rad){//点A绕原点旋转角度为rad
return Vector(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad));
} Vector normal(Vector A){//向量的法向量
double L = length(A);
return Vector(-A.y / L, A.x / L);
} double cross(Vector A, Vector B){//叉乘
return A.x * B.y - A.y * B.x;
} int n;
Point p[];
double ra[]; void input(){
cin>> n;
for(int i = ; i < n; ++i){
cin>> p[i].x>> p[i].y>> ra[i];
if(dcmp(ra[i] - * acos(-1.0)) == || dcmp(ra[i]) == ){
//当输入的弧度为0或者2π时,都是没用的
ra[i] = ;
n--;
i--;
}
}
} Vector rotate_point(Vector A){//将A点绕n个点旋转
for(int i = ; i < n; ++i){
A = p[i] + rotate(A - p[i], ra[i]);
}
return A;
} Vector mid_point(Point A, Point B){//求两点之间的中点
return Vector((A.x + B.x) / , (A.y + B.y) / );
} Point get_line_intersection(Point P, Vector v, Point Q, Vector w){//两直线求交点,《算法入门经典训练之南》几何
Vector u = P - Q;
double t = cross(w, u) / cross(v, w);
return P + v * t;
} void solve(){
Point t1[], t2[], mid[], vec[];
t1[].x = -;
t1[].y = -;
t1[].x = -;
t1[].y = -;
for(int i = ; i < ; ++i){
t2[i] = rotate_point(t1[i]);
mid[i] = mid_point(t1[i], t2[i]);
vec[i] = normal(t1[i] - t2[i]);
}
Point ans = get_line_intersection(mid[], vec[], mid[], vec[]);//答案点A
double ansp = angle(t1[] - ans, t2[] - ans);//旋转角度P if(cross(t1[] - ans, t2[] - ans) < ){//判断是ansp 还是2π - ansp
ansp = * acos(-1.0) - ansp;
} if(dcmp(ans.x) == ){//加入答案是-1e-11,如果直接输出就会是-0.0000000000
ans.x = ;
}
if(dcmp(ans.y) == ){
ans.y = ;
} printf("%.10lf %.10lf %.10lf\n", ans.x, ans.y, ansp);
} int main(){
//freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
int t;
cin>> t;
while(t--){
input();
solve();
}
return ;
}

AC代码

hdu 4998的更多相关文章

  1. HDU 4998 Rotate (计算几何)

    HDU 4998 Rotate (计算几何) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4998 Description Noting is more ...

  2. hdu 4998 矩阵表示旋转

    http://acm.hdu.edu.cn/showproblem.php?pid=4998 http://blog.csdn.net/wcyoot/article/details/33310329 ...

  3. HDU 4998 Rotate --几何

    题意:给n个点(x,y,p),从1~n,一次每次所有点绕着第 i 个点(原来的)逆时针转pi个弧度,问最后所有点的位置相当于绕哪个点旋转多少弧度,求出那点X和弧度P 解法:直接模拟旋转,每次计算新的坐 ...

  4. HDU 4998 (点的旋转) Rotate

    为了寻找等效旋转操作,我们任选两个点P0和Q0,分别绕这n个点旋转一定的角度后最终得到Pn和Qn 然后已知:P0和Pn共圆,Q0和Qn共圆.所以要找的等效旋转点就是这两个线段的垂直平分线交点O. 等效 ...

  5. HDU 4998 Rotate

    题意: n次旋转  每次平面绕ai点旋转pi弧度  问  最后状态相当于初始状态绕A点旋转P弧度  A和P是多少 思路: 如果初始X点的最后状态为X'点  则圆心一定在X和X'连线的垂直平分线上  那 ...

  6. hdu 4998 Rotate 点的旋转 银牌题

    Rotate Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  7. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  8. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  9. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

随机推荐

  1. delphi 数组类型与数组指针的巧妙利用

    {本例通过存取结构, 慢慢引入了数组类型与指针的一些使用方法; 其中六个小例子的测试内容和结果都是一样的. ---------------------------------------------- ...

  2. Java 基本数据类型转换

    1. Integer/int  转 String Integer a = 1; (int a = 1) String b = Integer.toString(a); 2. float 转 Strin ...

  3. JBoss的安装与配置(对应eclipse配置)【转】

    安装JBoss纯粹是目的就是学习EJB3...至少现在是这样的 EJB需要运行在EJB容器中.每个J2EE应用服务器都含有EJB容器和Web容器.这样,既支持运行EJB,也可以运行Web应用 目前EJ ...

  4. Freemarker的初次使用之FTL标签嵌套与map的使用

    入职第二周了,在熟悉了公司自动化测试脚本的编写(使用什么数据库,使用哪种语言,框架带了哪些方法)后,现在开始熟悉模拟器,我们把请求发到服务器1,服务器1根据请求参数处理后将结果发给模拟器,模拟器根据服 ...

  5. 低功耗蓝牙4.0BLE编程-nrf51822开发(8)-GATT

    The Generic Attribute Profile (GATT)使用属性定义一个服务框架,定义了服务和特性的过程和数据格式,包含发现.读取.写入.通知指示特性和配置特性广播. GATT配置文件 ...

  6. angularJS自定义指令模板替换

    <html> <head> <meta charset="utf-8"/> <title></title> </h ...

  7. 行高不设单位的好处 line-height:1.8

    今天无意间看了到了line-height:1.8 感觉挺有意思的,然后翻了下行高的知识,发现还挺有文章的,不妨温故而知新. 先回顾下:顶线.中线.基线.底线 vertical-align是元素的垂直对 ...

  8. Linux的常用基本命令

    Linux的常用基本命令. 首先启动Linux.启动完毕后需要进行用户的登录,选择登陆的用户不同自然权限也不一样,其中“系统管理员”拥有最高权限. 在启动Linux后屏幕出现如下界面显示: …… Re ...

  9. pointer-events:none;穿透属性

    从属性字面上看可以理解为:手势时间无效. 当我们在ios下想复制一段文字是,不知道原因导致一些莫名的怪异现象:总是无法复制文字,却意外的发现无论怎么着复制的始终都是图片时, 当我们在一个半透明遮罩上想 ...

  10. js的执行顺序

    js是顺序执行的,但是在一个<script></script>标签中,后面的函数会预加载.如: <script type="text/javascript&qu ...