题目描述
我们有一个 n * m 的矩阵,
现在我会告诉你每一行和每一列的异或和
请求出任意一种可能的矩阵
数据范围
1<=n,m<=100
输入数据确保在int范围内
输入输出格式:
输入格式:
第一行:两个整数 n,m
第二行:n 个整数,表示每一行的异或和
第三行:m 个整数,表示每一列的异或和
输出格式:
一个满足以上条件的 n * m 的矩阵
样例
输入
2 3 2 9 5 3 13
输出
YES 3 4 5 6 7 8
解题思路
这是一道比较好的构造题,考虑构造好的矩阵转化成二进制位,相当于我们只需要构造一个01矩阵
那么我们先将左上角(n-1)*(m-1)先填上,后面直接利用异或和出解即可
AC Code
#include<cstdio> #include<cstdlib> #include<iostream> #include<iostream> #define ll long long #define N 101 using namespace std; int n,m,g[N][N],a[N],b[N]; int main() { cin>>n>>m; for(int i=1; i<=n; ++i)cin>>a[i]; for(int i=1; i<=m; ++i)cin>>b[i]; for(int i=0; i<30; ++i) { for(int j=1; j<n; ++j) for(int k=1; k<m; ++k)g[j][k]|=1<<i; int s1=0,s2=0; for(int j=1; j<n; ++j) if(((m-1)&1)^((bool)(a[j]&(1<<i))))s1^=1,g[j][m]|=1<<i; for(int j=1; j<m; ++j) if(((n-1)&1)^((bool)(b[j]&(1<<i))))s2^=1,g[n][j]|=1<<i; if((((bool)(b[m]&(1<<i)))^s1)!=(((bool)(a[n]&(1<<i)))^s2)) { puts("NO"); exit(0); } if(((bool)(b[m]&(1<<i)))^s1)g[n][m]|=1<<i; } puts("YES"); for(int i=1; i<=n; ++i,puts("")) for(int j=1; j<=m; ++j)printf("%d ",g[i][j]); return 0; }