B3930 [GESP202312 五级] 烹饪问题

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;
}
相关推荐
nashane1 小时前
HarmonyOS 6学习:Canvas性能优化与长截图流畅实现实战
学习·性能优化·harmonyos
许长安1 小时前
Redis 跳表实现详解
数据库·c++·经验分享·redis·笔记·缓存
JAVA学习通1 小时前
安脉盛 软件后端开发实习面经
java·开发语言
sycmancia1 小时前
Qt——Qt中的事件处理(一)
开发语言·qt
paeamecium1 小时前
【PAT甲级真题】- Shortest Distance (20)
数据结构·c++·算法·pat考试·pat
aisifang001 小时前
GPT-Image2去偏见技术新突破
人工智能·算法·机器学习
Halo_tjn1 小时前
Java IO流文件操作
java·开发语言
吴可可1231 小时前
点在线上判定与多段线分割
算法·c#
折哥的程序人生 · 物流技术专研2 小时前
《Java 100 天进阶之路》第23篇:缓冲区数据结构 ByteBuffer
java·开发语言·数据结构·后端·面试·求职招聘