HDU-#4364 Matrix operation(模拟+矩阵乘法)

       题目大意:给一个4*4的aes矩阵,输入一个4*4的mat矩阵。计算这两个矩阵相乘的结果。但是相乘要按照下面的定义进行:

           The addition operation is defined as: xor.
      The multiplication operation is defined as: 
           multiplication by 1 means no change
           multiplication by 2 means shifting to the left
           multiplication by 3 means shifting to the left and then performing xor with the initial unshifted value. 
      Notice:After each shifting, a conditional xor with 0x1B should be performed if the shifted value is larger than 0xFF.

             所有的加运算都定义为 xor运算。

          相乘的运算定义如下:

                 乘1则不作任何改变;

                 乘2则值向左移一位;

                 乘3则值左移一位,然后与之前的值进行 xor运算。

          注意:所有的左移,如果值大于0xFF,则要与0x1B进行 xor,并对(0xFF+1)取余。

       解题思路:该题就是利用新定义的矩阵相乘法则进行运算,因此,只要弄清楚上述的运算规则,直接进行模拟即可。详见code。

      题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=4364

     code:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int t;
int ans[4][4],mat[4][4];
int aes[4][4]={2,3,1,1,1,2,3,1,1,1,2,3,3,1,1,2};

int main(){
    scanf("%d",&t);
    while(t--){
        memset(ans,0,sizeof(ans)); //初始化
        for(int i=0;i<4;i++) //接收mat矩阵
            for(int j=0;j<4;j++)
                scanf("%X",&mat[i][j]);
        for(int i=0;i<4;i++){ //aes矩阵的行
            for(int j=0;j<4;j++){ //aes矩阵和mat矩阵的列
                for(int k=0;k<4;k++){ //mat矩阵的行
                    int tmp=mat[k][j]; //tmp来计算左移的值
                    tmp<<=1;//左移一位
                    if(tmp>0xFF)//如果左移后值大于0xFF
                        tmp=(tmp^0x1B)%(0xFF+1);
                    if(aes[i][k]==1) //与1相乘,mat中的值不变
                        ans[i][j]^=mat[k][j]; //结果相加用xor来替代
                    else if(aes[i][k]==2)//与2相乘,左移一位
                        ans[i][j]^=tmp;
                    else if(aes[i][k]==3){ //与3相乘,左移一位,然后和左移前的值xor.
                        tmp^=mat[k][j];
                        ans[i][j]^=tmp;
                    }
                }
            }
        }
        for(int i=0;i<4;i++){ //输出结果
            for(int j=0;j<3;j++)
                printf("%02X ",ans[i][j]); //注意前面不足位数,要补0
            printf("%02X\n",ans[i][3]);
        }
        if(t)printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值