• P2117 小Z的矩阵


     

    题目描述

    小Z最近迷上了矩阵,他定义了一个对于一种特殊矩阵的特征函数G。对于N*N的矩阵A,A的所有元素均为0或1,则G(A)等于所有A[i][j]*A[j][i]的和对2取余之后的结果。举一个例子:

    对于上图这个3*3矩阵A,G(A)=(1*1+1*0+1*1+0*1+1*1+1*0+1*1+ 0*1+0*0) mod 2=0

    当然询问一个矩阵的G值实在是太简单了。小Z在给出一个N*N矩阵的同时将给你Q个操作,操作描述如下:

    操作1:形如一个整数1和一个整数x,表示将第x行的元素全部“翻转”。

    操作2:形如一个整数2和一个整数x,表示将第x列的元素全部“翻转”。

    操作3:形如一个整数3,表示询问当前矩阵的特征值G。

    “翻转”的定义为将1变成0,将0变成1。

    输入输出格式

    输入格式:

     

    第1行:两个正整数N,Q。 N表示矩阵的行数(列数),Q表示询问的个数。

    接下来N行:一个N*N的矩阵A,0<=A[i][j]<=1。

    接下来Q行:Q个操作。

     

    输出格式:

     

    一行若干个数,中间没有空格,分别表示每个操作的结果(操作1和操作2不需要输出)。

    输入输出样例

    输入样例#1: 复制
    3 12
    1 1 1
    0 1 1
    1 0 0
    3
    2 3
    3
    2 2
    2 2
    1 3
    3
    3
    1 2
    2 1
    1 1
    3
    输出样例#1: 复制
    01001

    说明

    【数据规模】

    30% N<=100, Q<=10^5

    100% N<=1,000, Q <=5*10^5

    紫色诱惑二:

    算是一道数学找规律题,

    数据范围很大,

    模拟思路应该还能接受吧,题目怎么着,就怎么写,

    先看一下三十分纯模拟代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 using namespace std;
     7 
     8 int n,q,x[500002],y[500002],g;
     9 int a[1002][1002];
    10 
    11 int main()
    12 {
    13     scanf("%d%d",&n,&q);
    14     for(int i=1;i<=n;++i)
    15         for(int j=1;j<=n;++j)
    16             scanf("%d",&a[i][j]);
    17     for(int i=1;i<=q;++i)
    18     {
    19         scanf("%d",&x[i]);
    20         if(x[i]!=3)
    21             scanf("%d",&y[i]);            
    22     }
    23     for(int i=1;i<=q;++i)
    24     {
    25         if(x[i]==3)
    26         {
    27             for(int j=1;j<=n;++j)
    28                 for(int k=1;k<=n;++k)
    29                     g+=a[j][k]*a[k][j];
    30             printf("%d",g%2);
    31             g=0;
    32         } 
    33         else
    34         {
    35             if(x[i]==1)
    36             {
    37                 for(int j=1;j<=n;++j)
    38                     a[y[i]][j]=!a[y[i]][j];
    39             }
    40             if(x[i]==2)
    41             {
    42                 for(int j=1;j<=n;++j)
    43                     a[j][y[i]]=!a[j][y[i]];
    44             }
    45         }    
    46     }
    47     return 0;
    48  } 

    能过三个点,其余都会T。

    不过正解,,好难想啊。。

    正解思路:

     输入的时候是这样的,然后可以手动模拟一下样例,,找找规律。。

    也许就找到了呢。

    看题目,题目中要输出所求g%2,

    任何一个正整数,%2后要么等于1,要么等于0,就这两种情况。

    然后看要求的g的算数过程,

    是所有a[i][j]*a[j][i]的和,不难发现,除了行列相同时,也就是i==j时,其余所有的乘积都被加了两遍。

    那么除了对角线的话,

    我说的对角线只有这一条

    除了这个别的都加了两遍意味着什么?

    输入的这个矩阵中的元素要么是1,要么是0,

    那他们两两之间的乘积也是要么是1,要么是0,

    所以当i!=j的时候,其余所有要求的乘积相加一定是个偶数,

    (因为都会加两遍嘛,要么1+1,要么0+0,那这些两遍的和再相加就一定是偶数)。

    所以不看对角线的话,g%2一定=0,

    所以就直接不用管这些了,只看对角线

    刚开始输入的时候对角线元素如果出现1ans取反,(初始为0

    (然后这应该也是个规律吧。。。暂且不讨论这个)

    在下面q个操作中,有行取反的,也有列取反的,

    但无论是行取反,还是列取反,一次操作只会改变一次对角线上的一个值。(important)

    所以不管怎么着,只要出现取反操作,ans直接跟着取反就行了,

    然后要输出的时候,就输出ans。

    这种题边输入边输出也是可以的。

    还不理解可以结合代码,模拟样例来看。

    ac代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 using namespace std;
     7 
     8 int n,q,t,x,y,ans;
     9 
    10 int main()
    11 {
    12     scanf("%d%d",&n,&q);
    13     for(int i=1;i<=n;++i)
    14         for(int j=1;j<=n;++j)
    15         {
    16             scanf("%d",&t);
    17             if(i==j&&t) ans=!ans;
    18         }    
    19     for(int i=1;i<=q;++i)
    20     {
    21         scanf("%d",&x);
    22         if(x!=3) 
    23         {
    24             scanf("%d",&y);
    25             ans=!ans;
    26         }            
    27         else
    28             printf("%d",ans);    
    29     }
    30     return 0;
    31  } 

     我的表达可能有些不清,

    看不懂的话,可以看一下这个blog:

    http://www.cnblogs.com/cangT-Tlan/p/8017982.html

  • 相关阅读:
    C# Console.Read()和Console.ReadLine()的区别
    C#获取项目程序及运行路径的方法
    Thread理解
    ENVI 监督分类Max stdev from Mean 参数IDL中的设置
    C# 插件开发学习实例
    利用动软代码器自动生存三层架构
    结构体的对齐
    链表分类及应用
    指针
    双向循环链表
  • 原文地址:https://www.cnblogs.com/Mary-Sue/p/9125868.html
Copyright © 2020-2023  润新知