[BZOJ3517]-翻硬币-异或方程

说在前面

并没有什么想说的,但是要保持格式=w=


题目

BZOJ3517传送门

题面

有一个n行n列的棋盘,每个格子上都有一个硬币,且n为偶数。每个硬币要么是正面朝上,要么是反面朝上。每次操作你可以选定一个格子(x,y),然后将第x行和第y列的所有硬币都翻面。求将所有硬币都变成同一个面最少需要的操作数。
数据范围:n不超过1000

输入输出格式

输入格式:
第一行包含一个正整数n。
接下来n行,每行包含一个长度为n的01字符串,表示棋盘上硬币的状态。

输出格式:
仅包含一行,为最少需要的操作数。


解法

一开始看到这道题,me毫无思路
然后发现,要翻的一定要被翻奇数次,不翻的一定要被翻偶数次
然后发现如果把任意两行(或两列)交换不影响答案
然后联想到了异或方程,然后就没有然后了(于是去看了题解)
看完之后发现,这道题和me之前做过的一道题很像!

现在使用 x[i][j] x [ i ] [ j ] 来表示位于 i i j列的棋子是否翻动, a[i][j] a [ i ] [ j ] 表示原来的状态
现在假设我们把所有的硬币都翻成 0 0 ,那么可以写出方程:
x[1][j]^ ... . . . ^ x[n][j] x [ n ] [ j ] ^ x[i][1] x [ i ] [ 1 ] ^ ... . . . ^ x[i][j1] x [ i ] [ j − 1 ] ^ x[i][j+1] x [ i ] [ j + 1 ] ^ ... . . . ^ x[i][M] x [ i ] [ M ] ^ a[i][j]=0 a [ i ] [ j ] = 0 (注意式子里 x[i][j] x [ i ] [ j ] 这一项只出现一次),然后我们把 a[i][j] a [ i ] [ j ] 移动到等式右边

然后,我们把除了(i,j)的 第i行的所有式子 以及 第j列的所有式子,都和这个式子联立一下,发现等式左边只会剩下 x[i][j] x [ i ] [ j ] (显然,因为保证n为偶数, x[i][k] x [ i ] [ k ] 会在所有的 x[i][?] x [ i ] [ ? ] 中出现一次,总共出现n次所以就消掉了。而 x[i][j] x [ i ] [ j ] 会出现 2n1 2 ∗ n − 1 次,于是留了下来),然后等式右边就是 a[i][?] a [ i ] [ ? ] 以及 a[?][j] a [ ? ] [ j ] 的异或和,也就是「第i行的异或和」^「第j列的异或和」^「(i,j)原来的状态」

然后要把所有棋子全部翻成1,其实就是把所有的x取反。
很明显,各行各列的异或和可以在输入的时候就处理完毕,然后这题就做完了


下面是自带大常数的代码

代码?什么代码?me貌似还没有写代码 (~ ̄▽ ̄)
(对,你没有看错,嘴巴AC选手在此)


小结一下

me有在上面提到,和这道题很类似的一道题,题目大意是这样的:
给出一个N行M列的矩阵(长宽不超过200),每个格子都可以填0或1,要求填完之后满足以下要求:每个格子与其边相邻的格子 异或和为0,且至少有一个格子为1(不能全0)。输出任意一种方案,题目保证有解

这道题是这样的,可以发现一个性质,如果确定了第一行的所有数字,那么为了满足第一行的要求,第二行也就随之确定了,以此类推,整个矩阵都确定了。于是我们可以假设第1行第i列的格子填法为 x[i] x [ i ] ,那么可以用异或式表示出矩阵的每一个格子(比如 x[1][1] x [ 1 ] [ 1 ] ^ x[1][2] x [ 1 ] [ 2 ] ^ x[2][1]=0x[2][1]=x[1][1] x [ 2 ] [ 1 ] = 0 ⟹ x [ 2 ] [ 1 ] = x [ 1 ] [ 1 ] ^ x[1][2] x [ 1 ] [ 2 ] ),以此类推,把第M+1行也这样表示出来。因为第M+1行不存在,于是这一行全部为0,由此可以得到N个方程,高斯消元解方程就可以了。(如果出现了自由元,全部设为1即可,题目保证有解)

这两道题的做法可以说是比较相似了,都是异或之后需要满足一些条件,然后把每个位置选1还是选0设成未知数然后解方程。感觉这个方法应该对某类型的题都适用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值