IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 2022牛客寒假2 小沙的数数(数学规律题 异或运算) -> 正文阅读

[数据结构与算法]2022牛客寒假2 小沙的数数(数学规律题 异或运算)

在这里插入图片描述
在这里插入图片描述

题意:

任意一个长度为 na 数组,已知其总和 a[+]m,问:有多少种不同的 a 数组,使得其 总异或和 a[⊕] 达到最大值

思路:

观察题目给定数据范围,可知肯定又是找规律了。

当直接想发现不出什么规律时,我们可以尝试的写写暴力求解的程序,我们以 n = 3 为例(当 n = 1 or 2 时直接在草稿纸上计算),m 自定义输入,计算出可能的种类数 cnt,以及所有可能结果中的 a 数组的最大异或和 mx

下面的程序建议copy到本地编译器上运行(注意本程序仅代表 n = 3m 为任意值 的情况)

#include<bits/stdc++.h>

using namespace std;

string trans(int x)     //返回一个整数的二进制表示的 string
{
        string s;
        for(int i=0; i<32; ++i)
        {
                int t = x >> i & 1;
                s += to_string(t);
        }
        while(s.back()=='0' && s.size()!=1) s.pop_back();
        reverse(s.begin(), s.end());
        return s;
}

int main()
{
        int m;
        while(printf("输入 a 数组总和 m:\n\n"), cin>>m)
        {
                cout<<"a 数组总和 m 的二进制表示:"<<trans(m)<<endl;
                puts("");
                int mx = -1;
                int cnt = 0;
                printf("当 a 数组异或和达到最大时,a1、a2、a3具体有以下情况:\n\n");
                for(int a1=0; a1<=m; ++a1)
                {
                        for(int a2=0; a2<=m; ++a2)
                        {
                                for(int a3=0; a3<=m; ++a3)
                                {
                                        if(a1+a2+a3==m)
                                        {
                                                mx = max(mx, a1 ^ a2 ^ a3);
                                                if((a1 ^ a2 ^ a3)==m)
                                                {
                                                        ++cnt, cout<<"a 数组:"<<a1<<' '<<a2<<' '<<a3<<endl;
                                                        cout<<"a1 二进制表示 "<<trans(a1)<<'\n';
                                                        cout<<"a2 二进制表示 "<<trans(a2)<<'\n';
                                                        cout<<"a3 二进制表示 "<<trans(a3)<<'\n';
                                                        puts("");
                                                }
                                        }
                                }
                        }

                }
                cout<<"最大异或和 mx "<<mx<<endl;
                cout<<"异或和最大时,a 数组可能的种类数:cnt "<<cnt<<endl;
                puts("");
        }

        return 0;
}

通过多次输入 m,并运行程序输出结果,我们可以初步得出结论:

对于一个包含 n 个元素的 a 数组,当其总和为 m 时,其最大异或和即为 m

这个结论的得出不一定要根据上面的暴力程序才能得到,通过在草稿纸上写几组样例也可以得出。(对于 多个数 的 异或运算,即 按位 进行“不进位加法”,根据这一原则在草稿纸上演算即可

由上面得出的结论,对于一个长为 n,总和为 ma 数组,其 异或和取最大值 时我们可以轻易 构造出一个方案

即:首元素为 m,其余 n - 1 个元素均为 0

进而根据异或运算的性质,我们发现对于 首元素中 1 所在位置,我们 任意将这些位置上的 1 随机 “覆盖” 到其它元素(0) 的对应位置,即可 得到其他的方案

由于对于首元素中的每个 1,都可以 选择 n 个位置进行覆盖,因此当 异或和取最大时,根据简单 乘法原理,得出:

总方案数 ans 等于 a 数组长度 n ^ 首元素中 1 的个数 count

最后,注意本题要开 long long,且观察到 n 给出的范围是大于 模数 mod 的范围的,因此输入的时候就要先对 n 取模。

代码:

#include<bits/stdc++.h>

using namespace std;

#define int long long
const int mod = 1e9+7;
inline int lowbit(int x) { return x & (-x); }

signed main()
{
    int n, m; cin>>n>>m;
    n = n % mod;//输入 n 之后要记得马上取模
    //求 m 的二进制表示中 1 的个数
    int cnt = 0;
    while(m) ++cnt, m -= lowbit(m);	
	//乘法原理求方案数
    int ans = 1;
    while(cnt--) ans = ans * n % mod;   
    
    cout<<ans<<'\n';

    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 11:44:27  更:2022-05-05 11:48:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:50:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码