题意:给定一个n*m的矩阵每行和每列所有元素的异或值,构造一个满足条件的矩阵,若没有输出No,若有则输出这个矩阵。
思路:设每行的异或值为a[1]、a[2]、... 、a[n],每列的异或值为b[1]、b[2]、... 、b[m];若a[1]^a[2]^ ... ^a[n] != b[1]^b[2]^ ... ^b[m],则矩阵不存在。为什么?因为a[1]^a[2]^ ... ^a[n]为矩阵所有元素的异或,而b[1]^b[2]^ ... ^b[m]也为矩阵所有元素的异或,所以矩阵若存在,两者必相等。若两者相等,则必然能构造出矩阵。
我们让第一行第一个元素为a[1]^b[2]^ ... ^b[m],第一行其余元素依次为b[2]、b[3]、... 、b[m]。第二行第一个元素为a[2],第三行第一个元素为a[3],...,第n行第一个元素为a[n],矩阵其余元素为0。这样构造的矩阵必然满足条件。(第一列的异或=a[1]^b[2]^ ... ^b[m]^a[2]^ ... ^a[n],其中,a[1]^a[2]^ ... ^a[n]=b[1]^b[2]^ ... ^b[m],所以第一列的异或=b[1]^b[2]^ ... ^b[m]^b[2]^ ... ^b[m]=b[1])。
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAX = 100+100;
ll row[MAX],col[MAX];
ll ans[MAX][MAX];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
ll tmp=0,res=0;
for(int i=0;i<n;i++){
scanf("%lld",&row[i]);
res^=row[i];
}
for(int i=0;i<m;i++){
scanf("%lld",&col[i]);
tmp^=col[i];
}
if(res!=tmp){
printf("NO\n");
return 0;
}
tmp^=col[0]^row[0];
ans[0][0]=tmp;
for(int i=1;i<m;i++)
ans[0][i]=col[i];
for(int i=1;i<n;i++)
ans[i][0]=row[i];
printf("YES\n");
for(int i=0;i<n;i++){
printf("%lld",ans[i][0]);
for(int j=1;j<m;j++)
printf(" %lld",ans[i][j]);
printf("\n");
}
return 0;
}