zoukankan      html  css  js  c++  java
  • P2129 L国的战斗续之多路出击

    题目描述

    这一次,L国决定军队分成n组,分布在各地,若以L国为原点,可以看作在一个直角坐标系内。但是他们都受统一的指挥,指令部共发出m个命令。命令有移动、上下转移和左右转移(瞬移??),但是由于某些奇奇怪怪的原因,军队收到命令总是有延迟,为了方便,军方已经写好一个栈(那还要我干嘛,自己都写好不就行了?),所以你要处理的顺序,应该是从后往前。

    输入输出格式

    输入格式:

    输入文件army.in包括n+m+1行

    第一行两个整数n、m

    接下来n行

    第i行有两个整数xi yi表示第i支军队的位置。

    又是m行

    每行首先是一个字符 C

    若C为m 则紧跟两个整数 p q 表示把每支军队的位置从(xi,yi)移到(xi+p.yi+q)

    若C为x 则表示把每支军队的位置从(xi,yi)移到(-xi,yi)

    若C为y 则表示把每支军队的位置从(xi,yi)移到(xi,-yi)

    输出格式:

    输出文件army.out包含n行

    第i行有两个整数xi、yi,表示第i支军队移动后的位置。

    输入输出样例

    输入样例#1: 
    3 3
    0 0
    4 -3
    6 7
    x
    m -1 2
    y
    
    输出样例#1: 
    1 2
    -3 5
    -5 -5
    

    说明

    对于30%的数据 1≤n≤1000 1≤m≤1000

    对于100%的数据 1≤n≤500000 1≤m≤500000 Ai在longint范围内

    Solution:

      本题矩阵乘法+模拟。

      对于每个给定的坐标,一系列的变换是一致的,不难发现给定的三种操作都很适合用矩阵去构造。

      所以我们可以对每种操作分别构建矩阵:

      1. $(x,y) ightarrow (-x,y)$:$egin{bmatrix}
     -1&  0& 0\
     0&  1& 0\
     0&  0& 1
    end{bmatrix}$

      2.$(x,y) ightarrow (x,-y)$:$egin{bmatrix}
     1&  0& 0\
     0&  -1& 0\
     0&  0& 1
    end{bmatrix}$

      3.$(x,y) ightarrow (x+p,y+q)$:$egin{bmatrix}
     1&  0& 0\
     0&  1& 0\
     p&  q& 1
    end{bmatrix}$

      然后就是矩阵乘法搞出最后的转移矩阵(注意乘的过程是倒序),用初始矩阵$egin{bmatrix}
    x_i & y_i & 1
    end{bmatrix}$乘转移矩阵就是答案了。

    代码:

    /*Code by 520 -- 9.30*/
    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    #define RE register
    #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
    #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
    #define clr(p) memset(&p,0,sizeof(p))
    using namespace std;
    const int N=500005;
    ll n,m,X[N],Y[N];
    struct matrix{
        ll a[4][4],r,c;    
    }op,t1,t2,t3;
    struct node{
        ll opt,p,q;    
    }t[N];
    
    ll gi(){
        ll a=0;char x=getchar();bool f=0;
        while((x<'0'||x>'9')&&x!='-') x=getchar();
        if(x=='-') x=getchar(),f=1;
        while(x>='0'&&x<='9') a=(a<<3)+(a<<1)+(x^48),x=getchar();
        return f?-a:a;    
    }
    
    il matrix mul(matrix x,matrix y){
        matrix tp;clr(tp);
        tp.r=x.r,tp.c=y.c;
        For(i,0,x.r-1) For(j,0,y.c-1) For(k,0,x.c-1)
        tp.a[i][j]+=x.a[i][k]*y.a[k][j];
        return tp;
    }
    
    int main(){
        n=gi(),m=gi();
        For(i,1,n) X[i]=gi(),Y[i]=gi();
        char s[2];
        For(i,1,m) {
            scanf("%s",s);
            if(s[0]=='x') t[i].opt=1;
            if(s[0]=='y') t[i].opt=2;
            if(s[0]=='m') t[i].opt=3,t[i].p=gi(),t[i].q=gi();
        }
        clr(op),clr(t1),clr(t2),clr(t3);
        op.r=op.c=3,t1.r=t1.c=3,t2.r=t2.c=3,t3.r=t3.c=3;
        t1.a[0][0]=-1,t1.a[1][1]=1,t1.a[2][2]=1,t2.a[0][0]=1,t2.a[1][1]=-1,t2.a[2][2]=1;
        op.a[0][0]=op.a[1][1]=op.a[2][2]=1;
        Bor(i,1,m) {
            if(t[i].opt==1) op=mul(op,t1);
            else if(t[i].opt==2) op=mul(op,t2);
            else {
                t3.a[0][0]=1,t3.a[1][1]=1,t3.a[2][0]=t[i].p,t3.a[2][1]=t[i].q,t3.a[2][2]=1;
                op=mul(op,t3);
            }
        }
        matrix ans;clr(ans);ans.r=1,ans.c=3;
        For(i,1,n) {
            ans.a[0][0]=X[i],ans.a[0][1]=Y[i],ans.a[0][2]=1;
            ans=mul(ans,op);
            printf("%lld %lld
    ",ans.a[0][0],ans.a[0][1]);
        }
        return 0;
    }
  • 相关阅读:
    关于MySql 数据库InnoDB存储引擎介绍
    .netcore 中使用开源的AOP框架 AspectCore
    C#关于反序列化实例时,接收实体字段少于或大于原实体对象 解析测试
    PostgreSQL TIMESTAMP类型 时间戳
    C# 新特性 操作符单?与??和 ?. 的使用
    PostgreSQL 常用函数
    AutoCAD.Net/C#.Net QQ群:193522571 previewicon生成的块图标太小,CMLContentSearchPreviews生成大的图片
    C#winform中OpenFileDialog的用法
    C# winform datagridview 无需点击两次即可编辑内嵌控件的方法和删除默认的空行的方法
    C# winform datagridview 内嵌控件值改变后立即触发事件,而不需要离开该单元格时才触发,此时需要用到dgv_CurrentCellDirtyStateChanged事件
  • 原文地址:https://www.cnblogs.com/five20/p/9747195.html
Copyright © 2011-2022 走看看