zoukankan      html  css  js  c++  java
  • 矩阵十题(1)

    Matrix67大牛关于矩阵经典题目的链接:http://www.matrix67.com/blog/archives/276/

    nyoj   298   点的变换

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=298

    经典题目1 
      
    给定n个点,m个操作,构造O(m+n)的算法输出m个操作后各点的位置。操作有平移、缩放、翻转和旋转
    这里的操作是对所有点同时进行的。其中翻转是以坐标轴为对称轴进行翻转(两种情况),旋转则以原点为中心。如果对每个点分别进行模拟,那么m个操作总共耗 时O(mn)。利用矩阵乘法可以在O(m)的时间里把所有操作合并为一个矩阵,然后每个点与该矩阵相乘即可直接得出最终该点的位置,总共耗时 O(m+n)。假设初始时某个点的坐标为x和y,下面5个矩阵可以分别对其进行平移、旋转、翻转和旋转操作。预先把所有m个操作所对应的矩阵全部乘起来, 再乘以(x,y,1),即可一步得出最终点的位置。

    注意:m个操作的矩阵连乘时必须左乘

    代码如下:

     1 #include<stdio.h>
     2 #include<math.h>
     3 #include<string.h>
     4 #define N 5
     5 struct Matrix
     6 {
     7     double a[N][N];
     8 }res,tmp,origin,ans,point[10000];
     9 Matrix mul(Matrix x,Matrix y)  //矩阵乘法
    10 {
    11     int i,j,k;
    12     memset(tmp.a,0,sizeof(tmp.a));
    13     for(i=1;i<=3;i++)
    14         for(j=1;j<=3;j++)
    15             for(k=1;k<=3;k++)
    16                 tmp.a[i][j]+=x.a[i][k]*y.a[k][j];
    17     return tmp;
    18 }
    19 int main()
    20 {
    21     int i,j,n,m;
    22     char c;
    23     double x,y,ang;
    24     scanf("%d%d",&n,&m);
    25     for(i=1;i<=n;i++)                                            //相当于 |x|
    26     {                                                            //       |y|
    27         scanf("%lf%lf",&point[i].a[1][1],&point[i].a[2][1]);     //       |1|
    28         point[i].a[3][1]=1;                                      
    29     }                                                            
    30     memset(res.a,0,sizeof(res.a));     //初始化为单位矩阵
    31     for(i=1;i<=3;i++)
    32         res.a[i][i]=1;
    33     for(i=1;i<=m;i++)     //将m个操作的矩阵连乘
    34     {
    35         getchar();
    36         scanf("%c",&c);
    37         memset(origin.a,0,sizeof(origin.a));  //初始化为单位矩阵
    38         for(j=1;j<=3;j++)
    39             origin.a[j][j]=1;
    40         if(c=='M')
    41         {                               //移动:相当于 |1 0 x|
    42             scanf("%lf%lf",&x,&y);      //             |0 1 y|
    43             origin.a[1][3]=x;           //             |0 0 1|
    44             origin.a[2][3]=y;
    45         }
    46         else if(c=='X')                 //绕x轴旋转:相当于 |1 0  0|
    47             origin.a[2][2]=-1;          //                  |0 -1 0|
    48                                         //                  |0 0  1|
    49 
    50         else if(c=='Y')                 //绕x轴旋转:相当于 |-1 0 0|
    51             origin.a[1][1]=-1;          //                  |0  1 0|
    52                                         //                  |0  0 1|
    53 
    54         else if(c=='S')                 //缩放:相当于 |x 0 0|
    55         {                               //             |0 x 0|
    56             scanf("%lf",&x);            //             |0 0 1|
    57             origin.a[1][1]=x;
    58             origin.a[2][2]=x;
    59         }
    60         else                            
    61         {                               //旋转:相当于 |cos(@) -sin(@) 0|
    62             scanf("%lf",&x);            //             |sin(@) cos(@)  0|
    63             ang=x/180*acos(-1.0);       //             |0      0       1|
    64             origin.a[1][1]=cos(ang);
    65             origin.a[1][2]=-sin(ang);
    66             origin.a[2][1]=sin(ang);
    67             origin.a[2][2]=cos(ang);
    68         }
    69         res=mul(origin,res);      //矩阵必须左乘
    70     }
    71     for(i=1;i<=n;i++)
    72     {
    73         ans=mul(res,point[i]);    //连乘后的矩阵乘以点的坐标
    74         printf("%.1f %.1f\n",ans.a[1][1],ans.a[2][1]);
    75     }
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    cv2.matchTemplate图片匹配
    pytorch 安装坑
    滑动轨迹函数记录
    selenium chrome开发者
    tp5 json()与json_encode()
    where 查询
    tp5.1 Class not found
    978. Longest Turbulent Subarray
    1004. Max Consecutive Ones III
    424. Longest Repeating Character Replacement
  • 原文地址:https://www.cnblogs.com/frog112111/p/3080678.html
Copyright © 2011-2022 走看看