符号三角形问题(Java)

news2025/1/20 1:45:13

符号三角形问题(Java)

文章目录

  • 符号三角形问题(Java)
    • 1、 前置介绍
    • 2、算法设计
    • 3、程序代码
    • 4、算法效率
    • 5、参考资料


在这里插入图片描述


1、 前置介绍

符号三角形定义

如下图所示,符号三角形是由14个“+” 号和14个"-"号组成的符号三角形。两个同号下面都是“+” 号, 两个异号下面都是”-“。

在一般情况下, 符号三角形的第一行有n个符号。符号三角形问题要求对于给定的n, 计算有多少
个不同的符号三角形,使其所含的"+ “和” - "的个数相同。

在这里插入图片描述

2、算法设计

对于符号三角形问题,用n元组X[l:n]表示符号三角形的第一行的n个符号。

x[i]=1 时,表示符号三角形的第一行的第t个符号为“+” ;当x[i]=0时,表示符号三角形的第一行的第t个号为"-"

由于x[i]是2值的, 所以在用回溯法解符号三角形问题时,可以用一棵完全二叉树来表示其解空间。

在符号三角形的第一行的前i个符号x[1:i]确定后, 就确定了一个由i*(i + 1)/2个符号组成的符号三角形。下一步确定x[i+l]的值后,只要在前面已确定的符号三角形的右边加一条边, 就可以扩展为x[1:i+l] 所相应的符号三角形。最终由x[l:n]所确定的符号三角形中包含的“+”个数与"-"个数同为n*(n+l)/4

  • 可行性约束条件

因此在回溯搜索过程中可用当前符号三角形所包含的“+”个数与"-"个数均不超过n*(n+l)/4 作为可行性约束, 用于剪去不满足约束的子树。

对于给定的n, 当n*(n+l)/2 为奇数时, 显然不存在所包含的“+” 个数与"-"个数相同的符号三角形。这种情况可以通过简单的判断加以处理。

3、程序代码

说明:

  • backtrack(level):搜索解空间中第level层子树

  • 主类的数据成员记录解空间中结点信息,以减少传给backtrack 的参数。

  • sum:记录当前已找到的“+”个数与"-"个数相同的符号三角形数。

  • 在算法backtrack中, 当i>n时,算法搜索至叶结点, 得到一个新的"+“个数与”-"个数相同的符号三角形,当前已找到符号三角形数sum增l

  • i<=n时, 当前扩展结点Z是解空间中的内部结点。该结点有x[i]=1 和x[i]=0共两个儿子结点。对当前扩展结点Z的每一个儿子结点, 计算其相应的符号三角形中“+”个数count与"-"个数,并以深度优先的方式递归地对可行子树搜索, 或剪去不可行子树。

public class Solution {

    static int n;           // 第一行符号个数
    static int half;        // n * (n+1) / 4        "+"/"-"符号个数
    static int count;       // 当前"+"个数
    static int[][] p;       // 符号三角形矩阵
    static long sum;        // 已找到的符号三角形数量

    public static void main(String[] args) {
        n = 4;
//        n = 7;
        count = 0;
        sum = 0;
        half = n * (n + 1) / 2;     // 先初始化为符号三角形中的符号总个数

        p = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= n; j++) {
                p[i][j] = 0;
            }
        }

        System.out.println("不同的符号三角形分别为:");
        compute(n);
        System.out.println("首行" + n + "个符号且符合题目要求的一共有" + sum + "种不同的符号三角形");
//        System.out.println("这" + sum + "种不同的符号三角形分别为:");

    }

    public static long compute(int firstCnt) {
        if (half % 2 == 1) {    // 符号总个数为奇数 不可能出现“+”、“-”个数相等的情况
            return 0;
        }
        half /= 2;             // 符号总个数为偶数   将 half设置为“+”(“-”)的个数
        backtrack(1);
        return sum;
    }

    private static void backtrack(int t) {
        // 当前“+”或者“-”符号个数已经达到n * (n + 1) / 4
        if ((count > half) || (t * (t - 1) / 2 - count > half)) {
            return;
        }
        // TODO 已经构造出一个符合要求的符号三角形,数量加1
        if (t > n) {
            sum++;
            // 打印符号三角形
            for (int i = 1; i <= n; i++) {
                for (int k = 1; k < i; k++) {
                    System.out.print(" ");
                }
                for (int j = 1; j <= n; j++) {
                    if (p[i][j] == 0 && j <= n - i + 1) {
                        System.out.print("+" + " ");
                    } else if (p[i][j] == 1 && j <= n - i + 1) {
                        System.out.print("-" + " ");
                    } else {
                        System.out.print("  ");
                    }
                }
                System.out.println();
            }
            System.out.println("----------------------------------");
        } else {
            // “+”、“-”用 0、1 代替(构造完全二叉树)
            for (int i = 0; i < 2; i++) {
                p[1][t] = i;
                count += i;
                // 上一行种只有大于等于2个符号才可以形成其下一行的一个符号
                for (int j = 2; j <= t; j++) {
                    // TODO 通过异或的方式求其余行数的放置方式
                    p[j][t - j + 1] = p[j - 1][t - j + 1] ^ p[j - 1][t - j + 2];
                    count += p[j][t - j + 1];
                }
                backtrack(t + 1);
                for (int j = 2; j <= t; j++) {
                    count -= p[j][t - j + 1];
                }
                count -= i;
            }
        }
    }
}

运行结果

在这里插入图片描述

4、算法效率

计算可行性约束需要O(n)时间,在最坏情况下有0(2n)个结点需要计算可行性约束,故解符号三角形问题的回溯算法backtrack所需的计算时间为O(n*2n)。

5、参考资料

  • 算法设计与分析(第四版)

结束!

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

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

相关文章

k8s镜像下载不下来?利用 github Action 自己动手一次性解决难题,丰衣足食

docker-image-syncer 无论是在学习k8s还是正式环境部署k8s中,第一步安装k8难倒了各大英雄好汉。原因是k8s 各种组件镜像在谷歌服务器上(k8s.gcr.io)&#xff0c;而我们有墙的存在&#xff0c;所以会经常性的下载失败。解决办法是搭梯子&#xff0c;或者是使用其他镜像源。 本…

有符号变量与无符号变量之间的值的转换

1、有符号变量与无符号变量之间的值的转换 程序例子 涉及到的内容是&#xff1a; 有符号变量和无符号变量之间的转换 溢出&#xff08;如何判断&#xff09; #include<stdio.h> char getchar(int x, int y){char c;unsigned int a x;(x y > 10 ) ? (c 1): (c 2…

Linux——I/O复用(select的用法)

一、I/O复用 定义&#xff1a;I/O 复用使得程序能同时监听多个文件描述符&#xff0c;这对于提高程序的性能至关重要。 网络程序在下列情况下需要使用 I/O 复用技术&#xff1a; ◼ TCP 服务器同时要处理监听套接字和连接套接字。◼ 服务器要同时处理 TCP 请求和 UDP 请求。◼ …

RT-Thread的设备模型

RTT内核对象——设备 RT-Thread有多种内核对象&#xff0c;其中设备device就是其中一种。 内核继承关系图如下&#xff1a; 设备继承关系图如下&#xff1a; I/O 设备模型框架 应用程序通过 I/O 设备管理接口获得正确的设备驱动&#xff0c;然后通过这个设备驱动与底层 I/O 硬…

ARM通用中断控制器GIC之中断处理状态机 Interrupt handling state machine

中断有四种状态&#xff1a;inactive&#xff0c;pending&#xff0c;active 和active and pending。而产生中断的方式有两种&#xff0c;一种是通过写pending寄存器&#xff0c;让中断进入pending状态&#xff0c;可以忽略是否真的有物理中断信号&#xff0c;让Distributor将该…

如何构建myquant量化策略?

对于如何构建myquant量化策略这个问题而言&#xff0c;就是获取量化股票接口的基础数据&#xff0c;然后有了基础数据&#xff0c;才能对数据进行加工处理&#xff0c;构建量化策略&#xff0c;进行量化分析&#xff0c;回测和回溯。myquant量化策略主要是基于python进行量化投…

案例实操 | 利用Lambda函数来进行特征工程,超方便的!!

特征工程对于我们在机器学习的建模当中扮演着至关重要的角色&#xff0c;要是这一环节做得好&#xff0c;模型的准确率以及性能就被大大地被提升&#xff0c;今天小编就通过Python当中的lambda函数来对数据集进行一次特征工程的操作&#xff0c;生成一些有用的有价值的特征出来…

nacos--基础--3.4--集成--spring--spring上下文中的一些关键的特性

nacos–基础–3.4–集成–spring–spring上下文中的一些关键的特性 1、spring上下文中的一些关键的特性 注解驱动依赖注入外部化配置事件驱动 2、注解驱动 2.1、 启用 Nacos EnableNacos 是一个模块驱动的注解EnableNacos 支持 Nacos Spring 的所有功能 服务发现&#xff1…

香港服务器托管带宽怎么选?

香港服务器托管时&#xff0c;带宽的选择非常重要&#xff0c;带宽用量的大小不同&#xff0c;最终的费用也就会不同。用户在香港托管服务器的时候&#xff0c;应该选择多大的带宽才合适呢?应该如何选择香港服务器带宽大小呢? 香港服务器托管带宽怎么选? 其实&#xff0c;大…

5G无线技术基础自学系列 | 无线电波传播模型

素材来源&#xff1a;《5G无线网络规划与优化》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 无线电波传播模型用于预测无线电波在各…

JAVA开发(JWTUtil工具类实现token源码赏析)

一、token解决问题的背景&#xff1a; 1、 单点登录&#xff0c; 2、分布式登录状态&#xff0c; 3、在信任期内 避免 重新输入用户名密码登录。 4、跨系统免登陆等。 5、一些接口的请求权限验证。 总结以上token最终都是为了解决在在分布式系统中信任期内 避免 重新输入用户名…

如何选择合适的统计学方法

一般来说&#xff0c;使用哪种统计方法&#xff0c;取决于我们的应用场景、我们的研究目的是什么。 这里面一个麻烦的地方在于&#xff0c;不管你使用哪种统计方法&#xff0c;似乎都可以得出一个’结果’或一个p值&#xff0c;但这个结果有没有意义就两说了。 在我看来&…

【WEB安全】Xstream最新反序列化poc执行报错问题

前言 最近有个需求&#xff0c;用Xstream反序列化打个内存马&#xff0c;从通用性来讲&#xff0c;肯定用1.4.17的洞去打应用范围最广。众所周知&#xff0c;Xstream官方会提供其漏洞的poc。在我实验之下&#xff0c;1.4.17的几个poc只要涉及到任意java代码执行的都会报错&…

VMware创建共享文件夹并实现文件传输(Windows主机,Ubuntu虚拟机)

文章目录创建共享文件夹安装/更新VMware tool挂载共享文件夹共享文件夹的实现更改配置项&#xff0c;实现自动挂载&#xff08;推荐直接用这个&#xff09;数据传输参考博客创建共享文件夹 1、开启虚拟机的共享文件夹配置 首先在虚拟机中打开设置&#xff0c;在选项中点击共享…

Java springboot+vue+MySQLJava大型CRM客户关系管理源码带手机端和小程序源码 Java客户全流程高效管理CRM系统源码

springbootvue MySQL数据库 1. 前端&#xff1a;Vue 2. 后端&#xff1a;Spring boot 3. 数据库&#xff1a;MySQL 源码已经亲测 1. 前端&#xff1a;Vue 2. 后端&#xff1a;Spring boot 3. 数据库&#xff1a;MySQL 小程序是用UNIAPP开发的。 后台登录账户&#xff1a…

(附源码)springboot智能服药提醒app 毕业设计 102151

基于springboot智能服药提醒app 摘 要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;智能服药提醒app程序被用户…

平均价格算法:TWAP vs. VWAP

时间加权平均价格 (TWAP) 和成交量加权平均价格 (VWAP) 算法应用不同的方法来计算资产价格&#xff0c;这是所有去中心化金融 (DeFi) 原语的组成部分。 在本文中&#xff0c;我们介绍了 TWAP 和 VWAP 算法之间的差异&#xff0c;解释了它们如何在区块链环境中为资产定价&#…

化学工程与装备杂志化学工程与装备杂志社化学工程与装备编辑部2022年第10期目录

科学研究与开发《化学工程与装备》投稿&#xff1a;cnqikantg126.com 槐木活性炭处理生活废水的研究 孔繁铸;高丽娟;赵开创;钱程; 1-3 基于Pumplinx的水泵机械密封温升仿真研究 赵雪飞;贾红杰;李雪峰;李雷;王景新;张晓辉; 4-728 全固态石墨烯-Ag/AgCl海洋电场探测电…

功率放大器的输入阻抗和输出阻抗是交流还是直流电阻

功率放大器的输入阻抗和输出阻抗一般是指交流电阻。交流电阻指一些伏安特性曲线的斜率。所以放大器输入阻抗和输出阻抗都是理论分析计算为主&#xff0c;而不使用万用表测量其大小。 输入阻抗一般是指电路输入端的等效阻抗&#xff0c;输入端加上一个电压源U&#xff0c;测量输…

WRF模式安装+详细运行教程

安装教程在安装之前&#xff0c;首先需要去查看自己的 Linux 系统&#xff08;虚拟机或者服 务器&#xff09;上的编译环境&#xff0c;也就是确定自己是否安装编译器或安装了哪种编 译器。&#xff08;因为安装过程需要选择编译器&#xff09;常用的编译器分为三种系列&#x…