蓝桥杯学习-14子集枚举,二进制枚举

news2025/3/27 23:55:32

子集枚举

一、回溯3-子集枚举(递归实现指数型枚举)

一旦涉及选与不选,删和不删,留和不留-->两种状态-->就要想到子集枚举

image-20250320215536930

例题1–递归实现指数型枚举19685

image-20250320221938056

其实看不懂这个题目,好奇怪的题目。根据老师的解析来写。
大致理解为从1-n中,输出所有的组合数就对了。
我知道了,就是要按照题目的要求来,要先判断0不选,再判断1选。具体看代码更了解。

暴力做法

假设n=3.

public class Main {
    static int[] st = new int[10];
    //主逻辑函数
    public static void solve(){
        int n = 3;
        for (int i = 0; i <=1; i++) {//表示选或不选
            st[1] = i;
            for (int j = 0; j <= 1; j++) {//表示选或不选
                st[2] = j;
                for (int k = 0; k <= 1; k++) {//表示选或不选
                    st[3] = k;
                    for (int l = 1; l <= 3; l++) {
                        //选中的输出
                        if(st[l] == 1) System.out.print(l);
                    }
                    System.out.println();
                }
            }
        }
    }
    public static void main(String[] args) {
        solve();
    }
}

使用回溯dfs来实现

image-20250321213009196

import java.util.Scanner;

//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class Main {
    static int n;
    static int[] st = new int[20];
    //递归函数
    public static void dfs(int u){
        if(u > n){
            //一次结束,输出结果
            for (int l = 1; l <= n; l++) {
                //选中的输出
                if(st[l] == 1) System.out.print(l + " ");
            }
            System.out.println();
            return;//这里要返回,因为?
        }
        for (int i = 0; i <= 1; i++) {
            st[u] = i;
            dfs(u + 1);//下一个数选或不选
        }
    }
    //主逻辑函数
    public static void solve(){
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        dfs(1);
//        for (int i = 0; i <=1; i++) {//表示选或不选
//            st[1] = i;
//            for (int j = 0; j <= 1; j++) {//表示选或不选
//                st[2] = j;
//                for (int k = 0; k <= 1; k++) {//表示选或不选
//                    st[3] = k;
//                    for (int l = 1; l <= 3; l++) {
//                        //选中的输出
//                        if(st[l] == 1) System.out.print(l);
//                    }
//                    System.out.println();
//                }
//            }
//        }
    }
    public static void main(String[] args) {
        solve();
    }
}
特别注意输出的格式问题,空格或者逗号特别注意,总因为这个没通过!!!

使用二进制枚举来实现

import java.util.*;
//s
public class Main {
  static int n;

    public static void solve(){
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        for (int i = 0; i < (1<<n); i++) {//0-7
            for (int j = n-1, k = 1; j >= 0; j--, k++) {
                if((i>>j&1) == 1){
                    //选中
                    System.out.print(k + " ");
                }
            }
            System.out.println();
        }
    }
    public static void main(String[] args) {
        solve();
    }
}

例题2–19880

例题3–蛋糕的美味值8664

package huisu;

import java.util.Scanner;

public class TasteCake {
    static int[] cake = new int[30];
    static int[] st = new int[30];
    static int n,k;
    static int max;

    //获得最大的总和
    public static void getMax(){
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            if(st[i] == 1){
                //被选中并且美味值小于k
                sum += cake[i];
            }
        }
        //结束后返回目前最大值
        if(sum < k){
            max = Math.max(sum,max);
        }
    }
    //递归
    public static void dfs(int u){//u表示第几个蛋糕
        if(u > n){
            //表示n个蛋糕选与不选完了
            getMax();
            return;
        }
        for (int i = 0; i <= 1; i++) {//选与不选
            st[u] = i;
            dfs(u + 1);//下一个蛋糕
        }
    }
    //主逻辑函数
    public static void solve(){
        Scanner sc = new Scanner(System.in);
        //输入n,k
        n = sc.nextInt();
        k = sc.nextInt();
        //输入蛋糕的美味值
        for (int i = 1; i <= n; i++) {
            cake[i] = sc.nextInt();
        }
        //递归
        dfs(1);
        //输出结果
        System.out.println(max);
    }
    public static void main(String[] args) {
        solve();
    }
}

注意:
一定要看清题目啊,看题目和观察样例。
这里是要选出的蛋糕的总值小于k,而不是选出的每一个小于k的。
我第一次写理解为后面那一种,就错了。
其实看样例也能看出来。
题目真难理解。。。

例题4–luoguP1036

二、二进制枚举

思想就是把选与不选,留与不留等两种状态的问题转换为二进制的01,0表示不选,1表示选。

前提

位运算

位运算(&、|、^、~、>>、 | 菜鸟教程

计算机对二进制数据进行的运算(如加、减、乘、除)被称为位运算,即对二进制数的每一位进行操作的运算。与直接使用 +、-、*、/ 运算符相比,合理运用位运算可以显著提高代码在机器上的执行效率。

符号描述运算规则
&两个位都为1时,结果才为1
|两个位都为0时,结果才为0
^异或两个位相同为0,相异为1
~取反0变1,1变0
<<左移各二进位全部左移若干位,高位丢弃,低位补0
>>右移各二进位全部右移若干位,高位补0或符号位补齐

按位与运算符(&)

定义:对参与运算的两个数据的二进制位进行"与"运算。

运算规则

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

总结:只有两位同时为1时,结果才为1,否则结果为0。

例如:3 & 50000 0011 & 0000 0101 = 0000 0001,因此 3 & 5 的值为1。

注意:负数按补码形式参与按位与运算。

用途

  1. 清零:如果想将一个单元清零,只要与一个各位都为零的数值相与,结果为零。

  2. 取一个数的指定位:例如,取数 X = 1010 1110 的低4位,只需另找一个数 Y = 0000 1111,然后 X & Y = 0000 1110 即可得到 X 的指定位。

  3. 判断奇偶:通过判断最未位是0还是1来决定奇偶,可以用 if ((a & 1) == 0) 代替 if (a % 2 == 0) 来判断 a 是否为偶数。

左移运算符(<<)

定义:将一个运算对象的各二进制位全部左移若干位,高位丢弃,低位补0。

例如,设 a = 1010 1110a = a << 2a 的二进制位左移2位、右补0,即得 a = 1011 1000

若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。

右移运算符(>>)

定义:将一个数的各二进制位全部右移若干位,高位补0或补符号位,右边丢弃。

例如,a = a >> 2a 的二进制位右移2位,左补0 或补符号位,具体取决于数的正负。

操作数每右移一位,相当于该数除以2。

思想

image-20250322215034778

image-20250322215210933

模板

package erjinzhimeiju;

public class Test1 {
    public static void main(String[] args) {
        int n = 3;
        //n=3即三位二进制数
        //共有(1<<n)种排列方式(1为选中,0为没选)
        for (int i = 0; i < (1<<n); i++) {//0-7
            //循环每一种排列方式
            for (int j = n-1, k = 1; j >= 0; j--, k++) {
                //取出每种排列方式的最后一位数,并判断输出
                //为什么j从n-1到0呢,因为要从头开始判断二进制数的各个位。
                if((i>>j&1) == 1){  //取出右移后的最后一位
                    //选中
                    System.out.print(k + " ");
                }
            }
            System.out.println();
        }
    }
}
///
"C:\Program Files\Java\jdk1.8.0_201\bin\java.exe" 

3 
2 
2 3 
1 
1 3 
1 2 
1 2 3 

Process finished with exit code 0
二进制枚举的时间复杂度是n*2^n

例题–五子棋对弈lanqiao19694

思路,对于这种落子问题,虽然有两个主体,但只对一个主体来说,依旧是选与不选的情况,-->子集枚举-->二进制枚举/递归实现指数型枚举?
1.想要平局,肯定是白棋13个对黑棋12个。
2.用1表示白棋,用0表示黑棋。
3.用二进制枚举来枚举每一种情况,只有白棋即1的数量等于13时,才进行一个平局的判断。若是平局则ans加加
4.对于判断平局,因为用1表示白棋,用0表示黑棋。
所以只要横竖线以及主副对角线数组的值不要等于0或者5即可。
5.注意:循环的时候先将情况放在一维数组上,后面判断再放到二维数组进行判断。
package erjinzhimeiju;

public class Test2 {
    static int n = 25;
    static int ans = 0;
    static int[] a = new int[30];//记录棋局
    static int[][] b = new int[10][10];//把棋局放在二维数组更好判断情况

    //判断在铺满棋盘的情况下是否为平局
    public static boolean check(){
        int pos = 0;
        //把棋局铺到棋盘上
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                b[i][j] = a[pos++];
            }
        }
        for (int i = 0; i < 5; i++) {
            int col = 0;//行
            int row = 0;//列
            for (int j = 0; j < 5; j++) {
                col = col + b[i][j];
                row = row + b[j][i];
            }
            if (col == 0 || col == 5 || row == 0 || row == 5)
                return false;//不是平局
        }
        //横竖没问题判断对角线
        int b1 = 0;//主对角线
        int b2 = 0;//副对角线
        for (int i = 0; i < 5; i++) {
            b1 = b1 + b[i][i];
            b2 = b2 + b[i][4-i];
        }
        if(b1 == 0 || b1 == 5 || b2 == 0 || b2 == 5)
            return false;//不是平局

        //都判断完了就是平局
        return true;
    }
    //主逻辑函数
    public static void solve(){
        for (int i = 0; i < (1<<n); i++) {//共2^n种情况
            int s = 0;//记录白棋的个数
            for (int j = 0; j < n; j++) {
                if((i>>j&1) == 1){
                    //选中
                    s++;
                }
                a[j] = i>>j&1;
            }
            if(s != 13) continue;//不满13个肯定不能是平局
            //都铺满棋盘后判断是否有连线情况发生
            if(check()){
                ans++;
            }
        }

        System.out.println(ans);



    }
    public static void main(String[] args) {
        solve();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2321129.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人工智能时代大学教育范式重构:基于AI编程思维的能力培养路径研究

人工智能技术的快速发展正在重塑高等教育的内容与方法。本文以AI编程教育为切入点&#xff0c;通过文献分析与案例研究&#xff0c;探讨AI时代大学教育的核心能力需求与教学范式转型路径。研究发现&#xff0c;AI编程中蕴含的系统性思维训练、项目架构能力和元认知能力培养机制…

<数据集>轨道异物识别数据集<目标检测>

数据集下载链接&#xff1a;https://download.csdn.net/download/qq_53332949/90527370 数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;1659张 标注数量(xml文件个数)&#xff1a;1659 标注数量(txt文件个数)&#xff1a;1659 标注类别数&#xff1a;6 标注类别…

Pyecharts功能详解与实战示例

一、Pyecharts简介 Pyecharts是一个基于Python的开源数据可视化库&#xff0c;它基于百度的Echarts库&#xff0c;提供了丰富的图表类型和强大的交互功能。通过Pyecharts&#xff0c;你可以轻松创建各种精美的图表&#xff0c;如折线图、柱状图、饼图、散点图、地图等&#xf…

EasyUI数据表格中嵌入下拉框

效果 代码 $(function () {// 标记当前正在编辑的行var editorIndex -1;var data [{code: 1,name: 1,price: 1,status: 0},{code: 2,name: 2,price: 2,status: 1}]$(#dg).datagrid({data: data,onDblClickCell:function (index, field, value) {var dg $(this);if(field ! …

C语言:扫雷

在编程的世界里&#xff0c;扫雷游戏是一个经典的实践项目。它不仅能帮助我们巩固编程知识&#xff0c;还能锻炼逻辑思维和解决问题的能力。今天&#xff0c;就让我们一起用 C 语言来实现这个有趣的游戏&#xff0c;并且通过图文并茂的方式&#xff0c;让每一步都清晰易懂 1. 游…

操作系统必知的面试题

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

清华大学.智灵动力-《DeepSeek行业应用实践报告》附PPT下载方法

导 读INTRODUCTION 今天分享是由清华大学.智灵动力&#xff1a;《DeepSeek行业应用实践报告》&#xff0c;主要介绍了DeepSeek模型的概述、优势、使用技巧、与其他模型的对比&#xff0c;以及在多个行业中的应用和未来发展趋势。为理解DeepSeek模型的应用和未来发展提供了深入的…

可视化图解算法:链表的奇偶重排(排序链表)

1. 题目 描述 给定一个单链表&#xff0c;请设定一个函数&#xff0c;将链表的奇数位节点和偶数位节点分别放在一起&#xff0c;重排后输出。 注意是节点的编号而非节点的数值。 数据范围&#xff1a;节点数量满足 0≤n≤105&#xff0c;节点中的值都满足 0≤val≤10000 要…

SAP Activate Methodology in a Nutshell Phases of SAP Activate Methodology

SAP Activate Methodology in a Nutshell Phases of SAP Activate Methodology

开源AI大模型、AI智能名片与S2B2C商城小程序源码:实体店引流的破局之道

摘要&#xff1a;本文聚焦实体店引流困境&#xff0c;提出基于"开源AI大模型AI智能名片S2B2C商城小程序源码"的技术整合方案。通过深度解析各技术核心机制与协同逻辑&#xff0c;结合明源云地产营销、杭州美甲店裂变等实际案例&#xff0c;论证其对流量精准获取、客户…

JVM 02

今天是2025/03/23 19:07 day 10 总路线请移步主页Java大纲相关文章 今天进行JVM 3,4 个模块的归纳 首先是JVM的相关内容概括的思维导图 3. 类加载机制 加载过程 加载&#xff08;Loading&#xff09; 通过类全限定名获取类的二进制字节流&#xff08;如从JAR包、网络、动态…

pyecharts在jupyter notebook中不能够渲染图表问题。

在使用jupyter notebook中使用pyecharts绘制可视化图表的时候,发现图表不能渲染到页面中,生成的html是没问题的,本文主要解决在jupyter notebook中不能渲染这个问题。 1、原因分析 2、解决办法 如果是使用的虚拟环境,需要下你提前激活虚拟环境,再进行下列操作。 因为需要…

《AI大模型趣味实战 》第7集:多端适配 个人新闻头条 基于大模型和RSS聚合打造个人新闻电台(Flask WEB版) 1

AI大模型趣味实战 第7集&#xff1a;多端适配 个人新闻头条 基于大模型和RSS聚合打造个人新闻电台(Flask WEB版) 1 摘要 在信息爆炸的时代&#xff0c;如何高效获取和筛选感兴趣的新闻内容成为一个现实问题。本文将带领读者通过Python和Flask框架&#xff0c;结合大模型的强大…

基于Spring Boot的健身房管理系统的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

WSL Linux 子系统download

WSL各Linux 子系统下载 WSL Linux 最新下载 微软应用商店 | Microsoft StoreWSL Linux 历史版下载复制应用商店Linux地址到转换下载地址https://store.rg-adguard.net/ Version百度网盘离线下载OracleLinux提取

Qt中通过QLabel实时显示图像

Qt中的QLabel控件用于显示文本或图像&#xff0c;不提供用户交互功能。以下测试代码用于从内置摄像头获取图像并实时显示&#xff1a; Widgets_Test.h&#xff1a; class Widgets_Test : public QMainWindow {Q_OBJECTpublic:Widgets_Test(QWidget *parent nullptr);~Widgets…

基于springboot的校园资料分享平台(048)

摘要 随着信息互联网购物的飞速发展&#xff0c;国内放开了自媒体的政策&#xff0c;一般企业都开始开发属于自己内容分发平台的网站。本文介绍了校园资料分享平台的开发全过程。通过分析企业对于校园资料分享平台的需求&#xff0c;创建了一个计算机管理校园资料分享平台的方案…

CS2 demo manager 安装

CS2DM CS Demo Managerhttps://cs-demo-manager.com/PostgreSQL&#xff08;CS2DM需要17以上&#xff09; EDB: Open-Source, Enterprise Postgres Database Managementhttps://www.enterprisedb.com/downloads/postgres-postgresql-downloads 新CS2dm现在打开是这样的&…

奇怪的异形选项卡样式、弧形边框选项卡

<template><div :class"$options.name"><div class"tab">默认选项卡</div><div class"tab" active>选中选项卡</div><el-divider /><el-tabs v-model"tabActiveName" tab-click"(t…

3.23 代码随想录第二十四天打卡

122.买卖股票的最佳时机II (1)题目描述: (2)解题思路: class Solution { public:int maxProfit(vector<int>& prices) {int result 0;for (int i 1; i < prices.size(); i) {result max(prices[i] - prices[i - 1], 0);}return result;} }; (3)总结: 1.假…