CodeForces - 1016D Vasya And The Matrix

题意:

输入n,m 表示一个n*m的矩阵

输入n个数 表示每行的异或和

输入m个数 表示每列的异或和

如果能构造这样的矩阵输出YES并打印其中一个矩阵

否则输出NO

思路:

首先 YES的条件是 所有行的异或和 suma = 所有列的异或和 sumb = 矩阵每个数的异或和

我们由异或性质可得 0异或任何一个数 = 他本身0 ^ a = a

所以我们让每一列的最后一行数为他的列异或和 其他都为0

比如一个4*2矩阵的列异或和是 4 2

0 0

0 0

0 0

4 2

同理 我们让每一行的最后一列数为他的行异或和 其他都为0

我们来看一下样例1

2 3

2 9

5 3 13

按照上面的方法 我们这样构筑这个矩形

0 0 2

5 3 

那(n,m)是多少呢 我们不妨设这个数为x

因为所有行的异或和 suma = a[1] ^ a[2] ^ a[3]...^ a[n] 

所有列的异或和 sumb = b[1] ^ b[2] ^ b[3]...^ b[m]

又因为 x ^ y = z ----> x ^ z = y

所以  

a[1] ^ a[2] ^ a[3]...^ a[n-1] =  suma ^ a[n] 

b[1] ^ b[2] ^ b[3]...^ b[m-1] = sumb ^ b[m]

而(n,m)这个数x满足

x ^ (a[1] ^ a[2] ^ a[3]...^ a[n-1]) = b[m] 即 x ^  suma ^ a[n] = b[m]

x ^ (b[1] ^ b[2] ^ b[3]...^ b[m-1]) = a[n] 即 x ^  sumb ^ b[m] = a[n]

两条式子都可以得到 x = suma(或sumb) ^ a[n] ^ b[m]

那么这个矩形就是

0 0 2

5 3 15

下面丢一个抄的代码

代码:

#include
#include
#include
#include
#define N 105
using namespace std;
int c[N][N],a[N],b[N];
int n,m,suma,sumb;
int main()
{
	int i,j,k,x,y;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)scanf("%d",&a[i]),suma^=a[i];
	for(i=1;i<=m;i++)scanf("%d",&b[i]),sumb^=b[i];
	if(suma!=sumb)puts("NO");
	else
	{
		puts("YES");
		for(i=1;i<=n;i++)c[i][m]=a[i];
		for(i=1;i<=m;i++)c[n][i]=b[i];
		c[n][m]=suma^a[n]^b[m];
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=m;j++)printf("%d ",c[i][j]);
			puts("");
		}
	}
}

 

你可能感兴趣的:(CodeForces - 1016D Vasya And The Matrix)