CodeForces C - Boboniu and Bit Operations(思维)

题目 链接

题意

给出两个a,b序列,为每一个a[i]选一个b[j]得到他们的按位与(即a[i]&b[j]),把这些所有的结果按位或,求最小值。

简析

因为n,m都不大于200,可以先读入然后把每个组合的按位与求出来,就能够得到一个nm的矩阵,记录着每个按位与。
然后问题就转化为,对于一个n
m的矩阵,每行选一个数字出来,这n个数字的按位或最小。
要从答案出发!因为每个数字都不大于29,所以直接遍历答案从0 ~ 29,然后找出第一个合法的就是最小的答案。
判断合法的过程如下,
对于一个想要判断状态的x而言,如果他是合法的,那么每一行至少有一个数字k使得x | k == x。
直接暴力扫描,判断每行一个是否有1个这样的数,如果每行至少存在一个则欲判断的x合法。

时间复杂度分析

枚举答案29 * n * m
极限算力为500 * 200 * 200 = 20000000(2e7)

参考代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int N = 210;

int a[N],b[N],s[N][N];
int main() {
	freopen("in.txt", "r", stdin);
	int n, m;
	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 = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			s[i][j] = a[i] & b[j];

	for (int k = 0; k <= (1 << 9); k++) { // 枚举所有答案的可能性
		int cnt = 0;
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				if ((s[i][j] | k )== k) { // 如果每行存在一个数字与答案按位或等于答案,说明答案合法
					cnt++;
					break;
				}
			}
		}
		if (cnt == n) {
			cout << k << endl;
			break;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值