zoukankan      html  css  js  c++  java
  • NYOJ 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

    分析:假设依照题目描写叙述的那样模拟。肯定会超时。这时就要找一种高速变换的方法。


    这样就能够先算出经过M次变换后形成的终于矩形,然后用点的坐标乘以矩形就能够求出答案。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #define PI acos(-1.0)
    
    struct Matrix {
        double mat[3][3];
        Matrix() {
            memset(mat, 0, sizeof(mat));
            for(int i = 0; i < 3; i++)
                mat[i][i] = 1;
        }
    
        Matrix Multi(Matrix A, Matrix B) {
            Matrix res;
            for(int i = 0; i < 3; i++) {
                for(int j = 0; j < 3; j++) {
                    res.mat[i][j] = 0;
                    for(int k = 0; k < 3; k++) {
                        res.mat[i][j] = res.mat[i][j] + A.mat[i][k] * B.mat[k][j];
                    }
                }
            }
            return res;
        }
    
        Matrix Translation(Matrix A, double p, double q) { //向上平移p个单位,向右平移q个单位
            Matrix res;
            res.mat[0][2] = p;
            res.mat[1][2] = q;
            return Multi(res, A);
        }
    
        Matrix Scale(Matrix A, double p) { //缩放p倍
            Matrix res;
            res.mat[0][0] = res.mat[1][1]  = p;
            return Multi(res, A);
        }
    
        Matrix Turn_UD(Matrix A) { //坐标轴上下翻转
            Matrix res;
            res.mat[1][1] = -1;
            return Multi(res, A);
        }
    
        Matrix Turn_LR(Matrix A) { //坐标轴左右翻转
            Matrix res;
            res.mat[0][0] = -1;
            return Multi(res, A);
        }
    
        Matrix Rotate(Matrix A, double angle) { //绕原点逆时针旋转angle角度
            double rad = angle / 180.0 * PI;
            Matrix res;
            res.mat[0][0] = cos(rad); res.mat[0][1] = -sin(rad);
            res.mat[1][0] = sin(rad); res.mat[1][1] = cos(rad);
            return Multi(res, A);
        }
    };
    
    struct Point {
        double x, y;
    } P[10005];
    
    int main() {
        int n, m;
        char op[5];
        double x, y;
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; i++)
            scanf("%lf%lf", &P[i].x, &P[i].y);
        Matrix A;
        for(int i = 0; i < m; i++) {
            scanf("%s", op);
            if(op[0] == 'X') A = A.Turn_UD(A);
            else if(op[0] == 'Y') A = A.Turn_LR(A);
            else if(op[0] == 'M') {
                scanf("%lf%lf", &x, &y);
                A = A.Translation(A, x, y);
            }
            else if(op[0] == 'S') {
                scanf("%lf", &x);
                A = A.Scale(A, x);
            }
            else if(op[0] == 'R') {
                scanf("%lf", &x);
                A = A.Rotate(A, x);
            }
        }
        for(int i = 0; i < n; i++) {
            double xx = A.mat[0][0] * P[i].x + A.mat[0][1] * P[i].y + A.mat[0][2];
            double yy = A.mat[1][0] * P[i].x + A.mat[1][1] * P[i].y + A.mat[1][2];
            printf("%.1lf %.1lf
    ", xx, yy);
        }
        return 0;
    }

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    day63_django_html
    day62_django
    day20
    diango_自定义标签问题
    day64_django_orm
    day16_函数嵌套及对象
    day60_django
    pip 安装问题
    day13_文件操作
    文本溢出显示省略号(…) 小坦克
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4664617.html
Copyright © 2011-2022 走看看