2021图森未来杯 A.【Abstract Algebra】

(为防止误解题意,接下来我说的1,2,3,4号位分别代表矩阵的第一排第一列,第一排第二列,第二排第一列,第二排第二列的数字)

题目大意:现在我们有俩个初始矩阵分别为图片说明

现在给出一个矩阵图片说明

现在已知图片说明

我们要通过对A矩阵和B矩阵如何处理才能转化成X?(操作次数需要小于等于4,且操作只能是使用矩阵乘法)
输出第一行先输出操作次数m,接下来m行
输出每一步的操作过程,即对A怎么操作或者对B怎么操作,题目有多解,输出任意一种即可

由于操作步数的限制,我们要合理的规划每一步的操作,要对任意一个x矩阵都成立,那我们可以先试一下A矩阵和B矩阵对任意的一个X矩阵会产生什么样的影响
图片说明

通过图片我们可以很清楚的发现一个很重要的信息点,图片说明 的变化只是在二号位这个位置加1,即可以得知图片说明

这只是我们通过观察得到的一个信息点,其他的信息还没有利用上。
我们现在还知道一个很重要的信息就是图片说明

那么这告诉我们abcd中至少有一个位置是0,我们假设现在这个为0的位置是c,即图片说明
若c=0,我们可以推断出来,ad=1,那么分俩种情况,a=d=1或者a=d=-1
对应的俩个矩阵就分别是图片说明

这时候可以很明显想到我们前面发现的信息,说明图片说明
那么X2呢?看上图我们可以发现图片说明 可以起到取负的作用,我们,因此我们可以得到
图片说明

截至目前,我们已经走出了很大一步,就是将c等于0的情况全部转换为了AB矩阵的变化,且只需要操作1次或者2次(第二种情况属于操作俩次,这是题意说明的)

回到问题本身,假如我们每一次都要通过这样子思考来判断四个位置等于0的情况会不会太麻烦了,(内心OS:我tm线代学的不好看不出规律啊!!!),那我们换个角度思考一下,c=0的情况这么简单易懂,那我们能不能通过简单的变换(操作次数越少越简单越好,因为要让自己看懂嘛QAQ)让我其他位置等于0的情况也转换成c=0这种easy模式呢?答案是必然的

我们来举个可爱的栗子
现在我的a=0,即图片说明
我们的目标有俩个
1.把0位变到3号位
2.在满足0位是三号位的情况下,一号位和四号位相乘要等于1(这样子就是c=0的情况了)

回到最开始的那幅图,防止你们懒得翻和方便阅读,我再贴一次
图片说明
我们可以发现当我们用B矩阵左乘X矩阵时,可以将上下俩排互换位置
神奇地将0位从一号位转到了三号位,那我们现在要得到X,那不是很简单嘛,我们只需要将目标矩阵左乘一个B的逆矩阵不就得到X了吗?

图片说明
只用了简简单单一步操作就变成了我们最开始的c=0的情况,一切问题都轻松解决,这时候就只用考虑c=1&&b=-1或者c=-1&&b==1的这俩种对应c=0的俩种情况了

通过这个简单的例子,我们悟到了一个道理,噢,逆矩阵真是个神奇的东西。
那我们就继续来简单快速讨论一下b=0和d=0的情况吧

先来讨论d=0的情况,因为这个和a=0一样简单
我们通过图片观察就能发现只要用B矩阵右乘X矩阵,就能使第一列和第二列互换位置,之后的讨论和a=0的情况相同
图片说明

接下来考虑b=0的情况,我们通过上述得知左乘B矩阵可以使上下互换,右乘B矩阵可以使得左右互换,那tmd低能儿都知道了,我们只要先左乘一个B,再右乘一个B,那不是就可以将0位转到三号位了吗???
反过来即图片说明

至此,我们已经将四个位置等于0的情况全部转换为了0位等于三号位这个最简单的情况,且所有操作次数都控制在了三以内,这已经是最优解了,我们只需要简单模拟一下上述过程然后输出即可
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e7+5;
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }

int main()
{
    int _;_=read();while(_--)
    {
        int a=read(),b=read(),c=read(),d=read();
        if(a==0)
        {
            puts("2");
            if(c==1&&b==-1)
            {
                puts("B -1");
                printf("A %d\n",d);
            }
            else if(c==-1&&b==1)
            {
                puts("B 1");
                printf("A %d\n",-d);
            }
        }
        else if(b==0)
        {
            puts("3");
            if(a==1&&d==1)
            {
                puts("B 1");
                printf("A %d\n",-c);
                puts("B -1");
            }
            else if(a==-1&&d==-1)
            {
                puts("B -1");
                printf("A %d\n",c);
                puts("B -1");
            }
        }
        else if(c==0)
        {
            if(a==1&&d==1)
            {
                puts("1");
                printf("A %d\n",b);
            }
            else if(a==-1&&d==-1)
            {
                puts("2");
                puts("B 2");
                printf("A %d\n",-b);
            }
        }
        else if(d==0)
        {
            if(b==1&&c==-1)
            {
                puts("3");
                puts("B 2");
                printf("A %d\n",-a);
                puts("B -1");
            }
            else if(b==-1&&c==1)
            {
                puts("2");
                printf("A %d\n",a);
                puts("B -1");
            }
        }
    }
}
全部评论

相关推荐

刘湘_passion:太强了牛肉哥有被激励到
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务