zoukankan      html  css  js  c++  java
  • NYOJ298 点的变换 【矩阵乘法经典】

    任意门:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=298

    点的变换

    时间限制:2000 ms  |  内存限制:65535 KB
    难度:5
     
    描述

    平面上有不超过10000个点,坐标都是已知的,现在可能对所有的点做以下几种操作:

    平移一定距离(M),相对X轴上下翻转(X),相对Y轴左右翻转(Y),坐标缩小或放大一定的倍数(S),所有点对坐标原点逆时针旋转一定角度(R)。    

    操作的次数不超过1000000次,求最终所有点的坐标。

    提示:如果程序中用到PI的值,可以用acos(-1.0)获得。

     
    输入
    只有一组测试数据
    测试数据的第一行是两个整数N,M,分别表示点的个数与操作的个数(N<=10000,M<=1000000)
    随后的一行有N对数对,每个数对的第一个数表示一个点的x坐标,第二个数表示y坐标,这些点初始坐标大小绝对值不超过100。
    随后的M行,每行代表一种操作,行首是一个字符:
    首字符如果是M,则表示平移操作,该行后面将跟两个数x,y,表示把所有点按向量(x,y)平移;
    首字符如果是X,则表示把所有点相对于X轴进行上下翻转;
    首字符如果是Y,则表示把所有点相对于Y轴进行左右翻转;
    首字符如果是S,则随后将跟一个数P,表示坐标放大P倍;
    首字符如果是R,则随后将跟一个数A,表示所有点相对坐标原点逆时针旋转一定的角度A(单位是度)
    输出
    每行输出两个数,表示一个点的坐标(对结果四舍五入到小数点后1位,输出一位小数位)
    点的输出顺序应与输入顺序保持一致
    样例输入
    2 5
    1.0 2.0 2.0 3.0
    X
    Y
    M 2.0 3.0
    S 2.0
    R 180
    样例输出
    -2.0 -2.0
    0.0 0.0

    题意概括:如题干

    解题思路:

    点的变换即向量的变换,即转换为矩阵运算,因为就是做初等变换嘛。

    AC code:

      1 //题目链接 http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=298
      2 #include <cstdio>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cstring>
      6 #include <cmath>
      7 #define LL long long
      8 using namespace std;
      9 const int MAXN = 5;
     10 const int MAXS = 1e4+2;
     11 const double pi = acos(-1.0);
     12 int N, M;
     13 
     14 struct mat
     15 {
     16     double m[MAXN][MAXN];
     17 }base;
     18 mat pp[MAXS];
     19 
     20 mat muti(mat a, mat b)
     21 {
     22     mat res;
     23     memset(res.m, 0, sizeof(res.m));
     24     for(int i = 1; i <= 3; i++){
     25         for(int j = 1; j <= 3; j++)
     26         if(a.m[i][j]){
     27             for(int k = 1; k <= 3; k++)
     28                 res.m[i][k] = (res.m[i][k] + a.m[i][j] * b.m[j][k]);
     29         }
     30     }
     31     return res;
     32 }
     33 
     34 mat add(mat a, mat b)
     35 {
     36     mat res;
     37     memset(res.m, 0, sizeof(res.m));
     38     for(int i = 1; i <= 3; i++){
     39         for(int j = 1; j <= 3; j++){
     40             res.m[i][j] = (a.m[i][j] + b.m[i][j]);
     41         }
     42     }
     43     return res;
     44 }
     45 
     46 //mat qpow(mat a, int n)
     47 //{
     48 //    mat res;
     49 //    memset(res.m, 0, sizeof(res.m));
     50 //    for(int i = 1; i <= 3; i++) res.m[i][i] = 1;
     51 //
     52 //    while(n){
     53 //        if(n&1) res = muti(res, a);
     54 //        n>>=1;
     55 //        a = myti(a, a);
     56 //    }
     57 //    return res;
     58 //}
     59 
     60 int main()
     61 {
     62     char com;
     63     mat tmp;
     64     double a, b;
     65     scanf("%d %d", &N, &M);
     66     for(int i = 1; i <= N; i++){
     67         scanf("%lf %lf", &a, &b);
     68         pp[i].m[1][1] = a;
     69         pp[i].m[2][1] = b;
     70         pp[i].m[3][1] = 1;
     71     }
     72     memset(tmp.m, 0, sizeof(tmp.m));
     73     for(int i = 1; i <= 3; i++) tmp.m[i][i] = 1;
     74     while(M--){
     75         memset(base.m, 0, sizeof(base.m));
     76         for(int i = 1; i <= 3; i++) base.m[i][i] = 1;
     77         getchar();
     78         scanf("%c", &com);
     79         if(com == 'M'){
     80             scanf("%lf %lf", &a, &b);
     81             base.m[1][3] = a;
     82             base.m[2][3] = b;
     83         }
     84         else if(com == 'X'){
     85             base.m[2][2] = -1;
     86         }
     87         else if(com == 'Y'){
     88             base.m[1][1] = -1;
     89         }
     90         else if(com == 'S'){
     91             scanf("%lf", &a);
     92             base.m[1][1] = a;
     93             base.m[2][2] = a;
     94         }
     95         else if(com == 'R'){
     96             scanf("%lf", &a);
     97             a = a/180*pi;
     98             base.m[1][1] = cos(a);
     99             base.m[1][2] = -sin(a);
    100             base.m[2][1] = sin(a);
    101             base.m[2][2] = cos(a);
    102         }
    103         tmp = muti(base, tmp);
    104     }
    105     mat ans;
    106     for(int i = 1; i <= N; i++){
    107 //        pp[i] = muti(tmp, pp[i]);
    108 //        printf("%.1f %.1f
    ", pp[i].m[1][1], pp[i].m[2][1]);
    109         ans = muti(tmp, pp[i]);
    110         printf("%.1f %.1f
    ", ans.m[1][1], ans.m[2][1]);
    111     }
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    [SUCTF 2019]Game
    [RoarCTF2019]黄金6年
    espcms代码审计第一弹
    初识搜索
    安恒2018年三月月赛MISC蜘蛛侠呀
    [De1CTF 2019]SSRF Me
    网鼎杯 fakebook
    [0CTF 2016]piapiapia
    [RoarCTF 2019]Easy Java
    [CISCN2019 华北赛区 Day1 Web1]Dropbox
  • 原文地址:https://www.cnblogs.com/ymzjj/p/9926488.html
Copyright © 2011-2022 走看看