【思维题】CodeForce 1016D Vasya And The Matrix

版权声明:Johnson https://blog.csdn.net/m0_38055352/article/details/91469923

这段时间要沉迷刷题一段时间了,就让CSDN陪我一起吧!

一、题目大意

题目的大致意思是说给定一个矩阵的大小n和m,然后给定a数组,其中a[i]是第i行的按位异或的结果,给定b数组,其中b[j]是第j列按位异或的结果,要求求解是否存在这样的矩阵,满足题目给定的异或结果,如果有就输出。

二、题目思路以及AC代码

这道题一开始我想到了肯定不存在的条件,那就是所有a[i]的按位异或结果与所有b[j]的按位异或结果不同,这可以直接写式子证明。

然后我就没考虑到如果去构造如何要求的矩阵。最后还是通过看题解,恍然大悟。总之,做按位异或的题目,无非就是要利用其两个性质:① 0 ^ a = a ② a ^ a = 0,第一个的意思是0与任何数异或还是那个数本身,第二个的意思是任何数与自身异或,结果都为0。

这样我们可以按如下方式构造矩阵。对于给定a、b数组,我们令每一列的最后一行为这一列的异或结果,也就是b[j],然后每一列的其他位置为0。同理,我们令每一行的最后一列为这一行的异或结果,也就是a[i],然后每一行的其他位置为0。但你一做会发现,其他位置都没什么问题,但最右下角的那个元素是有冲突的,所以这个元素我们要单独进行确认,这也可以用公式进行推导。
在这里插入图片描述
在这里插入图片描述
因为bnm=anm,所以由上述式子联合可得:
在这里插入图片描述
由于我们设这个式子的左部为S,待求矩阵的所有元素的异或结果为sum,那么S和sum的按位异或其实就是anm

下面给出AC代码:

#include <iostream>
#define MAXN 105
using namespace std;

int n, m;
int a[MAXN];
int b[MAXN];

int main()
{
	cin >> n >> m;

	int suma = 0;
	int sumb = 0;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		suma ^= a[i];
	}
	for (int i = 0; i < m; i++) {
		cin >> b[i];
		sumb ^= b[i];
	}

	if (suma != sumb) {
		cout << "NO" << endl;
	}
	else {
		cout << "YES" << endl;
		int ab = suma ^ a[n - 1] ^ b[m - 1];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m ; j++) {
				if (i == n - 1 && j == m - 1) {
					cout << ab << " ";
				}
				else if (i == n - 1) {
					cout << b[j] << " ";
				}
				else if (j == m - 1) {
					cout << a[i] << " ";
				}
				else {
					cout << 0 << " ";
				}
			}
			cout << endl;
		}
	}

    return 0;
}

如果有问题,欢迎大家指正!!!

猜你喜欢

转载自blog.csdn.net/m0_38055352/article/details/91469923