HDU4998 Rotate (2014年鞍山赛区网络赛B题)

1.题目描述:点击打开链接

2.解题思路:本题属于几何变换专题,一开始想着随便枚举两个点,然后都进行一下旋转变换,最后利用原始点和旋转后的点所在直线的中垂线的交点求解。然而发现精度损失很大,而且可能有特殊情况没有考虑到。学习了一下几何变换的方法。

由于旋转操作相当于对一个点构成的矩阵和一个旋转矩阵做乘法运算。最基本的旋转变换就是任意一个点围绕原点进行逆时针旋转。如果改成围绕某个定点(x0,y0)进行旋转可以分解为三步:将被旋转点平移(-x0,-y0),进行基本旋转变换,再平移(x0,y0)。在矩阵中可以理解为三个变换矩阵相乘。本题中,经过n次旋转操作后,得到最终的旋转矩阵ans。通过解一个二元一次方程组即可求得最终的旋转点。

详细的几何变换的讲解请看:点击打开链接 ,本题即该博客的情况2.5的应用。

3.代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<functional>
using namespace std;

#define me(s) memset(s,0,sizeof(s))
#define pb push_back
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair <int, int> P;

const double eps=1e-8;
const double PI=acos(-1.0);

struct Tran  //定义一个结构体,支持输入操作,矩阵相乘操作
{
    double x,y,r;
    double v[3][3];
    Tran()
    {
       memset(v,0,sizeof(v));
    }
    void init()
    {
        scanf("%lf%lf%lf",&x,&y,&r);
        memset(v,0,sizeof(v));
        v[0][0]=cos(r);v[0][1]=sin(r);
        v[1][0]=-sin(r);v[1][1]=cos(r);
        v[2][0]=x*(1-cos(r))+y*sin(r);
        v[2][1]=y*(1-cos(r))-x*sin(r);
        v[2][2]=1;
    }
    Tran operator*(Tran c)
    {
        Tran ans;
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
            for(int k=0;k<3;k++)
            ans.v[i][j]+=v[i][k]*c.v[k][j];
        return ans;
    }
}tran[15];

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        Tran ans; //ans矩阵为旋转n次后的矩阵
        for(int i=0;i<3;i++)
            ans.v[i][i]=1;//设置初始矩阵为单位矩阵
        for(int i=0;i<n;i++)
           {
               tran[i].init();
               ans=ans*tran[i];//进行n次相乘
           }
        double r=atan2(ans.v[0][1],ans.v[0][0]);
        if(r<0)r=2*PI+r;
        double cosr=ans.v[0][0];
        double sinr=ans.v[0][1];
        double b2=1-cosr;
        double b1=sinr;
        double c1=ans.v[2][0];
        double c2=ans.v[2][1];
        double M=b2*b2+b1*b1;
        double x=(b2*c1-b1*c2)/M;//利用行列式求解x,y
        double y=(b2*c2+b1*c1)/M;
        printf("%.10lf %.10lf %.10lf\n",x,y,r);
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-27 11:14:41

HDU4998 Rotate (2014年鞍山赛区网络赛B题)的相关文章

HDU 5002 Tree (2014年鞍山赛区网络赛F题)

1.题目描述:点击打开链接 2.解题思路:LCT的模板题 3.代码: #include <cstdio> #include <cstdlib> #include <algorithm> #include <iostream> #include <vector> using namespace std; const int N = 111111; const int INF = 1111111111; int n, m; class LCT { p

HDU5006 Resistance (2014年鞍山赛区网络赛J题)

1.题目描述:点击打开链接 2.解题思路:本题利用缩点+高斯消元解决.本题的最大特点就是电阻非零即一,如果电阻为0,说明零点之间是等电位点,可以看做一个整体,自然可以想到先利用并查集进行缩点操作,将复杂的电路图转化为不相等的电位点构成的电路图.如果转换完毕后,发现s和t在一个集合中,说明两点之间是等电位的,等效电阻为0,否则,对转换后的图G'重新判断连通性,依然可以利用并查集解决,如果发现不连通,说明s与t之间开路,电阻为inf,否则,就可以根据tot个点的电位列写方程. 我们令有1A的电流从点

HDU5001 Walk (2014年鞍山赛区网络赛E题)

1.题目描述:点击打开链接 2.解题思路:本题利用矩阵快速幂+概率dp解决.根据题意可以画出来一个状态转移图,根据状态转移图不难得到一步转移概率矩阵,接下来的问题是:如何求解d步之内(包括d)均无法从其他点走到结点u的概率. 首先,既然无法到达结点u,那么出发的时候就不能选择该点.其次,为了使其他结点也无法到达结点u,可以将一步转移概率矩阵中跟结点u有关的概率全部置零.即表示u结点出发无法到达其他结点,其他结点也均无法到达u结点,这样就相当于把u结点从状态转移图中暂时删去了.然后根据马氏链的知识

HDU5003 Osu! (2014年鞍山赛区网络赛G题)

1.题目描述:点击打开链接 2.解题思路:本题是一道简单的排序题,按照题意排序计算即可. 3.代码: #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include&

HDU 4998 Rotate(计算几何)2014年鞍山赛区网络赛

Rotate                                                                           Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Special Judge Problem Description Noting is more interesting than rotation! Your litt

ZOJ 3814 Sawtooth Puzzle (2014年牡丹江赛区网络赛F题)

1.题目描写叙述:点击打开链接 2.解题思路:本题是一道隐式图的搜索题目.一般来说,这类题目首先要定义状态,接下来是弄清楚状态怎样转移,以及状态怎样判重,怎样推断当前状态是否和目标状态同样.至于求解最短路就是经常使用的BFS就可以. 接下来我们逐一展开讨论. 1.状态的定义:看到这道题,猛一下会想着把每一个字符分别用01表示,然后看成二进制码进行状态压缩,这个状态定义尽管能够,可是显然,状态过于精确和复杂,假设把一行给压缩成一个整数,那么一个完整的图案要用8*9.即72个数才干描写叙述.显然过于

ZOJ 3810 A Volcanic Island (2014年牡丹江赛区网络赛B题)

1.题目描写叙述:点击打开链接 2.解题思路:本题是四色定理的模板题.只是有几种情况要提前特判一下:n==1直接输出,1<n<5时候无解,n==6时候套用模板会出现同样的块.因此要特判一下.其它情况都能直接利用模板构造出来. 3.代码: #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<cassert> #include<string>

ZOJ 3818 Pretty Poem (2014年牡丹江赛区网络赛J题)

1.题目描述:点击打开链接 2.解题思路:本题是一道模拟题,输入一个串,要求判断是否形如"ABABA"或"ABABCAB".只需要对两种情况逐一尝试即可.然而这道题有诸多细节需要考虑.这里说一下我自己的方法. 首先,如果输入的串长度<5,那么直接输出No,或者去掉所有的标点后发现长度<5,输出No.长度上没问题后,写一个专门的solve(int type)函数,来判断是否是上述情况中的一种.对于第一种,只需要枚举A的长度即可,B的长度就是(len-3*i

2014 ACM/ICPC 鞍山赛区网络赛(清华命题)

为迎接10月17号清华命题的鞍山现场赛 杭电上的题目 Biconnected(hdu4997)      Rotate(hdu4998)     Overt(hdu4999)   Clone(hdu5000)   Walk(hdu5001)   LianLianKan   Rescue   Spy's Work   Color the Tree   The Ghost Blows Light   USACO ORZ   2013/8/27