解题:CQOI 2013 和谐矩阵

题面

踩踩时间复杂度不正确的高斯消元

首先可以发现第一行确定后就可以确定整个矩阵,所以可以枚举第一行的所有状态然后$O(n)$递推检查是否合法

$O(n)$递推的方法是这样的:设$pre$为上一行,$now$为当前行,$nxt$为递推出的下一行,$all$为列的全集,则可以直接用位运算完成递推:

$nxt=all\&((now<<1)xor(now>>1)xor$ $now$ $xor$ $pre)$

递推后第$n+1$行为空则说明可行

问题来了,第一行的状态有$O(2^{40})$种,会$T$。但是有一个鬼畜的性质是如果存在合法解一定有一个对称的合法解,然后就可以$O(n*2^{\frac{n}{2}})$出解了=。=

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=50;
 6 int mapp[N][N];
 7 long long n,m,mid,all,half;
 8 long long fir,las,noww,tmp;
 9 int check(int a,int b)
10 {
11     return mapp[a][b]^mapp[a-1][b]^mapp[a][b-1]^mapp[a][b+1];
12 }
13 int main ()
14 {
15     scanf("%lld%lld",&n,&m);
16     mid=(m+1)/2,all=(1ll<<m)-1,half=(1ll<<mid)-1;
17     for(int i=1;i<=half;i++)
18     {
19         fir=0;
20         for(int j=1;j<=mid;j++)
21             if(i&(1ll<<(j-1))) fir|=(1ll<<(j-1))|(1ll<<(m-j));
22         las=noww=all&(fir^(fir<<1)^(fir>>1)),tmp=fir;
23         for(int j=2;j<=n;j++)
24             las=noww,noww=all&(noww^(noww<<1)^(noww>>1)^tmp),tmp=las;
25         if(!noww) break;
26     }
27     for(int i=1;i<=m;i++)
28         mapp[1][i]=(fir&(1ll<<(i-1)))?1:0;
29     for(int i=2;i<=n;i++)
30         for(int j=1;j<=m;j++)
31             mapp[i][j]=check(i-1,j);
32     for(int i=1;i<=n;i++)
33     {
34         for(int j=1;j<=m;j++)
35             printf("%d ",mapp[i][j]);
36         printf("\n");
37     }
38     return 0;
39 }

原文地址:https://www.cnblogs.com/ydnhaha/p/9737308.html

时间: 2024-10-31 06:06:35

解题:CQOI 2013 和谐矩阵的相关文章

BZOJ 3503 CQOI 2014 和谐矩阵 高斯消元

题目大意:给出m和n,求出一种方案使得每一个点和周围的四个点的1的个数为偶数. 思路:根据题意可以列出m*n个异或方程,然后组成异或方程组.解这个异或方程组然后输出任意一个解就可以了. PS:值得注意的是,全是0肯定是一个解,显然你不能输出这个解.所以你需要让一个或一些自由元的值为1,至于怎么做,随便yy就行了. PS2:这个题的样例吞掉了空格,然而又是SPJ,所以就是wa..然后我wa了一下午.. CODE: #include <cstdio> #include <cstring>

【BZOJ 3503】 [Cqoi2014]和谐矩阵

3503: [Cqoi2014]和谐矩阵 Time Limit: 10 Sec Memory Limit: 128 MBSec Special Judge Submit: 493 Solved: 216 [Submit][Status][Discuss] Description 我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1.一个元素相邻的元素包括它本 身,及他上下左右的4个元素(如果存在). 给定矩阵的行数和列数,请计算并输出一个和谐的矩阵.注意:所有元素为0的矩阵是

【高斯消元】BZOJ3503 [Cqoi2014]和谐矩阵

3503: [Cqoi2014]和谐矩阵 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1197  Solved: 570[Submit][Status][Discuss] Description 我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1.一个元素相邻的元素包括它本 身,及他上下左右的4个元素(如果存在). 给定矩阵的行数和列数,请计算并输出一个和谐的矩阵.注意:所有元素为0的矩

BZOJ_3503_[Cqoi2014]和谐矩阵_高斯消元

题意: 我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1.一个元素相邻的元素包括它本身,及他上下左右的4个元素(如果存在).给定矩阵的行数和列数,请计算并输出一个和谐的矩阵.注意:所有元素为0的矩阵是不允许的. 分析: 考虑一种暴力,设n*m个未知数,列n*m个方程 高斯消元解方程,注意全零矩阵不合法 那我们如果发现有自由元就将它们置为1 代码: #include <stdio.h> #include <string.h> #include <algo

【BZOJ】【3503】【CQOI2014】和谐矩阵

高斯消元解Xor方程组 Orz ZYF o(︶︿︶)o 唉我的数学太烂了…… 错误思路:对每个格点进行标号,然后根据某5个异或和为0列方程组,高斯消元找自由元……(目测N^3会TLE) ZYF的正确思路: 如果第一行的数知道了,我们就可以推出其他行的数. 那么如何判断第一行的数的一种填法是否合法呢?很简单,我们递推出m+1行的数,当且仅当这一行都是0时满足题意. 那么,我们就有了一种想法. 直接把m+1行的每个数用x[1..n]表示出来,这一定是个系数只为0/1的式子.然后让这个异或值=0,就可

Luogu3164 CQOI2014 和谐矩阵 异或、高斯消元

传送门 题意:给出$N,M$,试构造一个$N \times M$的非全$0$矩阵,其中所有格子都满足:它和它上下左右四个格子的权值之和为偶数.$N , M \leq 40$ 可以依据题目中的条件列出有$N \times M$的元.$N \times M$个方程的异或方程组(异或方程组就是所有位置都是$1$或$0$,最右边一列的答案需要通过异或互相消除的方程组,一般在$mod\,2$意义下产生). 理论上元和方程组数量一致的时候每一个元都是有唯一解的,但是在有解的情况下,其中一些方程是线性相关的,

BZOJ3503: [Cqoi2014]和谐矩阵

题解: 如果第一行的数知道了,我们就可以推出其他行的数. 那么如何判断第一行的数的一种填法是否合法呢?很简单,我们递推出m+1行的数,当且仅当这一行都是0时满足题意. 那么,我们就有了一种想法. 直接把m+1行的每个数用x[1..n]表示出来,这一定是个系数只为0/1的式子.然后让这个异或值=0,就可以解异或方程组了. 系数怎么推呢? for1(i,n)b[1][i]=(ll)1<<i-1; for2(i,2,m+1) for1(j,n) b[i][j]=b[i-1][j]^b[i-1][j-

Bzoj3503--Cqoi2014和谐矩阵

原本想每个点建个五元异或方程组高斯消元解的,发现时间有点紧,就去压位卡常,结果调试的时候把自己挂在键盘上了.- -| 正解是从第一排推出第m+1排的异或表达式,然后因为m+1排的数全为0,转回来解这个异或方程组. 实现上我是消的对角线,消成上三角可能会快.出于习惯,我是把n,m互换了的. 代码: #include<bits/stdc++.h> #define INF 1000000000 #define LNF 100000000000000ll #define eps 1e-9 #defin

【BZOJ3503】【Cqoi2014】和谐矩阵 高斯消元,解异或方程组

#include <stdio.h> int main() { puts("转载请注明出处"); puts("地址:blog.csdn.net/vmurder/article/details/43699831"); } 题解: 随便搞搞就好. 自由元全当成1就好了么~~~ 不会异或方程组的移步这里[POJ1222]EXTENDED LIGHTS OUT 高斯消元.解异或方程组 代码: #include <cstdio> #include &l