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的更多相关文章
-
HDU 4998 Rotate (计算几何)
HDU 4998 Rotate (计算几何) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4998 Description Noting is more ...
-
hdu 4998 矩阵表示旋转
http://acm.hdu.edu.cn/showproblem.php?pid=4998 http://blog.csdn.net/wcyoot/article/details/33310329 ...
-
HDU 4998 Rotate --几何
题意:给n个点(x,y,p),从1~n,一次每次所有点绕着第 i 个点(原来的)逆时针转pi个弧度,问最后所有点的位置相当于绕哪个点旋转多少弧度,求出那点X和弧度P 解法:直接模拟旋转,每次计算新的坐 ...
-
HDU 4998 (点的旋转) Rotate
为了寻找等效旋转操作,我们任选两个点P0和Q0,分别绕这n个点旋转一定的角度后最终得到Pn和Qn 然后已知:P0和Pn共圆,Q0和Qn共圆.所以要找的等效旋转点就是这两个线段的垂直平分线交点O. 等效 ...
-
HDU 4998 Rotate
题意: n次旋转 每次平面绕ai点旋转pi弧度 问 最后状态相当于初始状态绕A点旋转P弧度 A和P是多少 思路: 如果初始X点的最后状态为X'点 则圆心一定在X和X'连线的垂直平分线上 那 ...
-
hdu 4998 Rotate 点的旋转 银牌题
Rotate Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
-
HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
-
【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
-
hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
随机推荐
-
[JavaCore]JAVA中的泛型
JAVA中的泛型 [更新总结] 泛型就是定义在类里面的一个类型,这个类型在编写类的时候是不确定的,而在初始化对象时,必须确定该类型:这个类型可以在一个在里定义多个:在一旦使用某种类型,在类方法中,那么 ...
-
C# 设置和获取一个字节的某一位的值的方法
自己工作中遇到需要对单字节的高位.低位进行赋值,即一个字节byte,想要给每一位都赋值,这个值是动态来的,是0或是1. 好不容易收集到一些珍贵资料,整理一下: 一.设置 方法code: /// < ...
-
python&#39;s descriptor II
[python's descriptor II] For instance, a.x has a lookup chain starting with a.__dict__['x'], then ty ...
-
UML视图(九)部署图
一.什么是部署图? 部署图对面向对象系统的物理方面建模,描写叙述系统执行时节点.构件实例及其对象的配置.主要用来在部署系统时涉及到的硬件(处理器和设备)进行建模. 二.部署图的组成元素? 部署图主要包 ...
- JDK内置工具使用
-
Python之路-文件操作(py3)
文件操作的基本步骤: 1.打开文件:f=open('filename'),with open('filename') as f 2.操作文件:增,删,改,查 3.关闭文件:f.close 打开文件 p ...
- spring的摘录
-
知识驱动对话-Learning to Select Knowledge for Response Generation in Dialog Systems-阅读笔记
今日看了一篇文章<Learning to Select Knowledge for Response Generation in Dialog Systems>,以知识信息.对话目标.对话 ...
-
服务发现 - consul 的介绍、部署和使用(转)
什么是服务发现 相关源码: spring cloud demo 微服务的框架体系中,服务发现是不能不提的一个模块.我相信了解或者熟悉微服务的童鞋应该都知道它的重要性.这里我只是简单的提一下,毕竟这不是 ...
-
【转】Linux下从TCP状态机,三次握手判断DDOS攻击
从TCP状态机判断DDOS攻击 一.TCP协议 TCP 协议是传送层的核心协议,提供了可靠面向连接的协议,分为三次握手和四次断开,在这个过程中TCP有个状态机,记录不同阶段的状态. 二. TCP握手和 ...