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;
}
相关推荐
架构师伯子明8 分钟前
Ros 学习十三:IK Demo
学习
小羊没烦恼!12 分钟前
关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁
java·服务器·网络·学习·负载均衡
will_net13 分钟前
apollo 站点部署&C#接入
开发语言·c#·apollo
幼儿园蛋小黄36 分钟前
从 STM32N647 的 AI 部署入门嵌入式:一条可落地的学习路线
人工智能·stm32·学习
晗夜未央1 小时前
任务队列反复失败,先分清重试、阻塞和结果待核对
开发语言·javascript
熊猫钓鱼>_>1 小时前
四种书签,一条时间线:一个读书 App 的记忆颗粒与它的边界案例【鸿蒙心迹】
开发语言·华为·ai编程·harmonyos·鸿蒙·openharmony·鸿蒙pc
丘山望岳1 小时前
单调栈和单调队列
数据结构
Fuyo_11191 小时前
C++ AVL树保姆级详解:从平衡因子到四大旋转机制
java·c++·算法
努力努力再努力wz1 小时前
【Lua 入门系列】Lua 函数深入理解:函数对象、多返回值、可变参数、闭包、递归与尾调用优化
开发语言·lua
jktantan2 小时前
每个节点 41 字节:把一棵百万节点树拆进 14 个 typed array
前端·javascript·vue.js·算法·typescript