题意:
输入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<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#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("");
}
}
}