C F 1119 C : R a m e s s e s a n d C o r n e r I n v e r s i o n CF1119C:Ramesses and Corner Inversion CF1119C:RamessesandCornerInversion
题目(后面有题意):
C. Ramesses and Corner Inversion
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Ramesses came to university to algorithms practice, and his professor, who is a fairly known programmer, gave him the following task.
You are given two matrices A A A and B B B of size n × m n\times m n×m, each of which consists of 0 0 0 and 1 1 1 only. You can apply the following operation to the matrix A A A arbitrary number of times: take any submatrix of the matrix a a a that has at least two rows and two columns, and invert the values in its corners (i.e. all corners of the submatrix that contain 0 0 0, will be replaced by 1 1 1, and all corners of the submatrix that contain 1 1 1, will be replaced by 0 0 0). You have to answer whether you can obtain the matrix b b b from the matrix a a a.
An example of the operation. The chosen submatrix is shown in blue and yellow, its corners are shown in yellow.
Ramesses don’t want to perform these operations by himself, so he asks you to answer this question.
A submatrix of matrix M M M is a matrix which consist of all elements which come from one of the rows with indices x 1 , x 1 + 1 , … , x 2 x1,x1+1,…,x2 x1,x1+1,…,x2 of matrix M M M and one of the columns with indices y 1 , y 1 + 1 , … , y 2 y1,y1+1,…,y2 y1,y1+1,…,y2 of matrix MM, where x 1 , x 2 , y 1 , y 2 x1,x2,y1,y2 x1,x2,y1,y2 are the edge rows and columns of the submatrix. In other words, a submatrix is a set of elements of source matrix which form a solid rectangle (i.e. without holes) with sides parallel to the sides of the original matrix. The corners of the submatrix are cells ( x 1 , y 1 ) , ( x 1 , y 2 ) , ( x 2 , y 1 ) , ( x 2 , y 2 ) (x1,y1), (x1,y2),(x2,y1),(x2,y2) (x1,y1),(x1,y2),(x2,y1),(x2,y2), where the cell ( i , j ) (i,j) (i,j) denotes the cell on the intersection of the i i i-th row and the j j j-th column.
Input
The first line contains two integers n n n and m m m (1≤n,m≤5001≤n,m≤500) — the number of rows and the number of columns in matrices A A A and B B B.
Each of the next n n n lines contain m m m integers: the j j j-th integer in the i i i-th line is the j j j-th element of the i i i-th row of the matrix A A A ( 0 ≤ A i j ≤ 1 0≤Aij≤1 0≤Aij≤1).
Each of the next n n n lines contain m m m integers: the j j j-th integer in the i i i-th line is the j j j-th element of the i i i-th row of the matrix B B B ( 0 ≤ B i j ≤ 1 0≤Bij≤1 0≤Bij≤1).
Output
Print “Yes” (without quotes) if it is possible to transform the matrix A A A to the matrix B B B using the operations described above, and “No” (without quotes), if it is not possible. You can print each letter in any case (upper or lower).
Examples
input
3 3
0 1 0
0 1 0
1 0 0
1 0 0
1 0 0
1 0 0
output
Yes
input
6 7
0 0 1 1 0 0 1
0 1 0 0 1 0 1
0 0 0 1 0 0 1
1 0 1 0 1 0 0
0 1 0 0 1 0 1
0 1 0 1 0 0 1
1 1 0 1 0 1 1
0 1 1 0 1 0 0
1 1 0 1 0 0 1
1 0 1 0 0 1 0
0 1 1 0 1 0 0
0 1 1 1 1 0 1
output
Yes
input
3 4
0 1 0 1
1 0 1 0
0 1 0 1
1 1 1 1
1 1 1 1
1 1 1 1
output
No
Note
The examples are explained below.
Example 1.
Example 2.
Example 3.
题意:
给你两个矩阵,定义一次操作为选取一个子矩阵的四个角,并将它们的值取反,请问能不能通过若干次操作使第一个矩阵变成第二个矩阵。
解析:通过观察可以发现,一次操作不会改变某一行奇偶性,那么直接判断两个矩阵的行奇偶性即可。
但是很容易注意到一次操作不止在一行或者一列操作,会不会出现某一行的奇偶性对上过后,另外的一行就对不上了。
也就是说这种思路是把操作的两行给拆分出来,对每一行的操作是奇偶性不变的前提下任意操作。但是拆分之后原来的两行的操作变成了一行的操作,恐怕考虑不全。
那么会有这种情况:
1 1 1 1 1 1 1 1
1 1 0 0 0 0 0 0
也就是说第一行的奇偶性使我们认为不需要操作,因为他们的奇偶性相同,同时第二行的奇偶性也是相同的,我们也认为他们是可以转换的。但是实际上并不是这样,两个矩阵之间并不能转换(分析可以得知)。
那么我们继续观察。
容易发现,两个矩阵的列对应的奇偶性不相同。
于是得出结论:当且仅当两个矩阵的行和列的奇偶性对应相同的时候,两个矩阵才可以互相转换。
证明:一次操作相当于同时维护了行与列的奇偶性。试想,假设要修改一个点,同时又要维护行和列的奇偶性,那么这一个点对应的行与列也一定会有需要修改的,而这一些修改有破坏了他们对应的奇偶性关系,那么我们可以再修改一个点来维护整个矩阵的奇偶性,这样,这个操作就变成了题目中的操作。
注意到取反相当于是^ 1 1 1,代码:
#include <bits/stdc++.h>
#define xx first
#define yy second
using namespace std;
const int N = 550;
int info[N << 1];
int main()
{
// freopen("data.in", "r", stdin);
int n, m;
scanf("%d%d", &n, &m);
for (int k = 1; k <= 2; k++)
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
int tmp;
scanf("%d", &tmp);
info[i] ^= tmp;
info[n + j] ^= tmp;
}
}
for (int i = 1; i <= m + n; i++)
if (info[i])
{
printf("No\n");
return 0;
}
printf("Yes\n");
return 0;
}