B3930 [GESP202312 五级] 烹饪问题
题目背景
对应的选择、判断题:https://ti.luogu.com.cn/problemset/1137
题目描述
有 N N N 种食材,编号从 1 1 1 至 N N N,其中第 i i i 种食材的美味度为 a i a_i ai。
不同食材之间的组合可能产生奇妙的化学反应。具体来说,如果两种食材的美味度分别为 x x x 和 y y y ,那么它们的契合度为 x\\ \\text{and}\\ y 。
其中, and \text{and} and 运算为按位与运算,需要先将两个运算数转换为二进制,然后在高位补足 ,再逐位进行与运算。例如, 12 12 12 与 6 6 6 的二进制表示分别为 1100 1100 1100 和 0110 0110 0110 ,将它们逐位进行与运算,得到 0100 0100 0100 ,转换为十进制得到 4,因此 12 and 6 = 4 12\ \text{and}\ 6 = 4 12 and 6=4。在 C++ 或 Python 中,可以直接使用 & 运算符表示与运算。
现在,请你找到契合度最高的两种食材,并输出它们的契合度。
输入格式
第一行一个整数 N N N,表示食材的种数。
接下来一行 N N N 个用空格隔开的整数,依次为 a 1 , ⋯ , a N a_1,\cdots,a_N a1,⋯,aN,表示各种食材的美味度。
输出格式
输出一行一个整数,表示最高的契合度。
输入输出样例 #1
输入 #1
3
1 2 3
输出 #1
2
输入输出样例 #2
输入 #2
5
5 6 2 10 13
输出 #2
8
说明/提示
样例解释 1
可以编号为 2 , 3 2,3 2,3 的食材之间的契合度为 2 and 3 = 2 2\ \text{and} \ 3=2 2 and 3=2,是所有食材两两之间最高的契合度。
样例解释 2
可以编号为 3 , 4 3,4 3,4 的食材之间的契合度为 10 and 13 = 8 10\ \text{and}\ 13=8 10 and 13=8,是所有食材两两之间最高的契合度。
数据范围
对于 40 % 40\% 40% 的测试点,保证 N ≤ 1 , 000 N \le 1,000 N≤1,000;
对于所有测试点,保证 N ≤ 10 6 N \le 10^6 N≤106, 0 ≤ a i ≤ 2 , 147 , 483 , 647 0\le a_i \le 2,147,483,647 0≤ai≤2,147,483,647。
cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[1000010]; // 存储所有美味度
ll n;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
for (ll i = 1; i <= n; i++) {
cin >> a[i];
}
ll ans = 0; // 当前能取到的最大值
/*
* 从高位到低位贪心
* 一共 30 位
*/
for (int bit = 30; bit >= 0; bit--) {
/*
* 尝试把当前这一位"强行设为 1"
* now 表示:ans 的基础上,新增这一位
*/
ll now = ans | (1LL << bit);
int cnt = 0; // 统计有多少个数支持这个 now
/*
* 检查所有数
* (a[i] & now) == now
* 含义:
* - a[i] 在 now 为 1 的位上,也必须为 1
* - 即:a[i] 包含 now 的所有 1
*/
for (int i = 1; i <= n; i++) {
if ((a[i] & now) == now) {
cnt++;
}
}
/*
* 如果至少有 2 个数满足
* 说明可以把这一位保留下来
*/
if (cnt >= 2) {
ans = now;
}
}
cout << ans << endl;
return 0;
}