codeforces1016D Vasya And The Matrix

C题写40多分钟,D题想不出,又靠rols上分,菜哭.jpg。rols的做法十分好理解,我们按二进制位数来考虑,看a数组中有多少个包含1<<i,b数组中有多少个包含1<<i,存到ca数组和cb数组中,如果个数奇偶性不一样,就是错的,否则就先安排那些同时给a和b添加上1<<i这一位的位置,给他们加上1<<i,如果ca数组还有剩余,也就是ca[0]>cb[0],那么久给ans[ca[j]][1]安排上,cb数组还有剩余,就给ans[1][cb[j]]安排上。

奇偶性不一样的时候,说明第一行或者第一列的1无法抵消变成相同的,那么就满足不了。

此题另外一种,cf官方题解直接给第一排第一列安排,其他全是0,然后比较一下ans[1][1]计算出来的是不是一样的就行了。然而我并没有想得很清楚,不过感觉大致是对的

#include<bits/stdc++.h>

using namespace std;

const int maxn=110;

int n,m;
int a[maxn],b[maxn],ca[maxn],cb[maxn];
long long ans[maxn][maxn];

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=m;i++)
		scanf("%d",&b[i]);
	for(int i=0;i<=30;i++)
	{
		ca[0]=cb[0]=0;
		for(int j=1;j<=n;j++)
			if((a[j]&(1<<i)))ca[++ca[0]]=j;
			
		for(int j=1;j<=m;j++)
			if((b[j]&(1<<i)))cb[++cb[0]]=j;
		if((ca[0]&1)!=(cb[0]&1))
		{
			printf("NO");
			return 0;
		}
		for(int j=1;j<=ca[0]&&j<=cb[0];j++)
			ans[ca[j]][cb[j]]+=(1<<i);
		if(ca[0]>cb[0])for(int j=cb[0]+1;j<=ca[0];j++)
			ans[ca[j]][1]+=(1<<i);
		else for(int j=ca[0]+1;j<=cb[0];j++)
			ans[1][cb[j]]+=(1<<i);
	}
	
	printf("YES\n");
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			printf("%lld%c",ans[i][j],(j==m?'\n':' '));
	
    return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/81488623