题目大意:给一个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;
}