HDU4364—十六进制矩阵运算

题意是给定一个状态矩阵,用该矩阵右乘一个已知的矩阵,该已知矩阵的元素是2或3或1,定义运算加法为按位异或,乘法有三种,当乘的数字是1时,不变,当乘的数字是2时,进行左移位运算,当乘的数字是3时,先进行左移位运算,然后与原来没进行移位操作的时候的这个数进行按位异或操作。每次移位操作后,如果所得的数字大于0xFF,则还要和0x1B进行按位异或操作。  要注意的一点就是进行完按位异或操作后,所得结果还可能超过0xFF,而题目要求每个矩阵元素只占1个字节,即8个二进制位,2个十六进制位,所以所得结果不能超出0xFF,所以当值大于0xFF时,要取余。还有一点注意的,空行只需在两种测试数据之间输出,最后不用输出。

#include 
#include 
using namespace std;
int mat[4][4]={2,3,1,1,1,2,3,1,1,1,2,3,3,1,1,2};
int state[4][4],ans[4][4];

void work()
{
    int i,j,k,temp1,temp2[4];
    for(i=0;i<4;i++)
    for(j=0;j<4;j++)
    {
        for(k=0;k<4;k++)
        {
            if(mat[i][k]==2)
            {
                temp1=state[k][j]<<1;
                if(temp1>0xFF)
                temp1^=0x1B;
                if(temp1>0xFF)
                temp1%=(0xFF+1);
            }
            else if(mat[i][k]==3)
            {
                temp1=state[k][j]<<1;
                if(temp1>0xFF)
                temp1^=0x1B;
                temp1^=state[k][j];
                if(temp1>0xFF)
                temp1%=(0xFF+1);
            }
            else
            temp1=state[k][j];
            temp2[k]=temp1;
        }
        for(k=1;k<4;k++)
        temp2[0]^=temp2[k];
        ans[i][j]=temp2[0];
    }
}

int main()
{
    int i,j,t;
    scanf("%d",&t);
    while(t--)
    {
        for(i=0;i<4;i++)
        for(j=0;j<4;j++)
        scanf("%X",&state[i][j]);
        work();
        for(i=0;i<4;i++)
        for(j=0;j<4;j++)
        if(j!=3)
        printf("%02X ",ans[i][j]);
        else
        printf("%02X\n",ans[i][j]);
        if(t!=0)
        printf("\n");
    }
    return 0;
}


 

你可能感兴趣的:(acm之路)