问题描述:

下图是由14个“+”和14个“-”组成的符号三角形。2个同号下面都是“+”,2个异号下面都是“-”:

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

解题思路:

1、不断改变第一行的每个符号,搜索符合条件的解,可以使用递归回溯。

为了便于运算,设+ 为0,- 为1,这样可以使用异或运算符表示符号三角形的关系:
            ++为+即0^0=0, --为+即1^1=0, +-为-即0^1=1, -+为-即1^0=1

2、因为两种符号个数相同,可以对题解树剪枝

当所有符号总数为奇数时无解,当某种符号超过总数一半时无解

算法设计:

在符号三角形的第一行的前i个符号x[1:i]确定后,就确定了一个由i*(i+1)/2个符号组成的符号三角形。

下一步确定了x[1:i]的值后,只要在前面确定的符号三角形的右边加一条边,就可以扩展为x[1:i]所对应的符号三角形。

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

代码:

需要的数据:

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

初始化及计算:

public static float Compute(int nn) {n = nn;count = 0;sum = 0;half = (n*(n+1))>>1;if((half>>1)<<1 != half) {return 0;}half = half>>1;p = new int[n+1][n+1];backtrack(1);return sum;}

回溯算法1(仅用于计算行数或者列数为n的符号三角形的总数,没有显示符号三角形的功能,但是是核心代码):

public static void backtrack01(int t) {if(count>half || (t*(t-1)/2-count > half)) {//对题解树的剪枝return;}if(t>n) {sum++;//符号三角形的总数目+1}else {//每个位置都有两种情况0,1for(int i = 0;i<2;i++) {p[1][t] = i;count += i;//对"-"个数进行技术,为了进行剪枝操作//接下来绘制其余的n-1行for(int j = 2;j<=t;j++) {//通过异或的方式求其余行数的放置方式p[j][t-j+1] = p[j-1][t-j+1]^p[j-1][t-j+2];count += p[j][t-j+1];  }backtrack01(t+1);//恢复现场for(int j = 2;j<=t;j++) {count -= p[j][t-j+1];}count -= i;}}}

回溯算法2(具备打印符号三角形的功能):

public static void backtrack(int t) {if((count>half)||(t*(t-1)/2-count > half)) //对题解树的剪枝return;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,1for(int i =0;i<2;i++) {p[1][t] = i;count += i;//计算“-”的个数//接下来绘制其余的n-1行for(int j = 2;j<=t;j++) {//通过异或的方式求其余行数的放置方式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;}}}

完整代码:

package tri;public class TRAN {static int n;//第一行的符号个数static int half;//n*(n+1)/4static int count;//当前“+”或者“-”的个数static int[][] p;//符号三角形矩阵static long sum;//已找到的符号三角形的个数public static float Compute(int nn) {n = nn;count = 0;sum = 0;half = (n*(n+1))>>1;if((half>>1)<<1 != half) {return 0;}half = half>>1;p = new int[n+1][n+1];backtrack(1);return sum;}/*** 算法1* @param t*//*public static void backtrack01(int t) {if(count>half || (t*(t-1)/2-count > half) {//对题解树的剪枝return;}if(t>n) {sum++;//符号三角形的总数目+1}else {//每个位置都有两种情况0,1for(int i = 0;i<2;i++) {p[1][t] = i;count += i;//对"-"个数进行技术,为了进行剪枝操作//接下来绘制其余的n-1行for(int j = 2;j<=t;j++) {//通过异或的方式求其余行数的放置方式p[j][t-j+1] = p[j-1][t-j+1]^p[j-1][t-j+2];count += p[j][t-j+1];   }backtrack01(t+1);//恢复现场for(int j = 2;j<=t;j++) {count -= p[j][t-j+1];}count -= i;}}}*/public static void backtrack(int t) {if((count>half)||((t*(t-1)/2-count > half)) //对题解树的剪枝return;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,1for(int i =0;i<2;i++) {p[1][t] = i;count += i;//计算“-”的个数//接下来绘制其余的n-1行for(int j = 2;j<=t;j++) {//通过异或的方式求其余行数的放置方式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;}}}public static void main(String[] args) {// TODO Auto-generated method stubfloat SUM = Compute(4);    System.out.print("总数: " + SUM);}}

以行数为4的符号三角形为例,显示输出如下:

符号三角形问题—回溯算法—java实现相关推荐

  1. 0-1背包问题—回溯算法—java实现

    0-1背包问题 [问题描述] 有n种可选物品1,-,n ,放入容量为c的背包内,使装入的物品具有最大效益. 表示 n :物品个数 c :背包容量 p1,p2, -, pn:个体物品效益值 w1,w2, ...

  2. java符号三角形问题_实验四 回溯算法和分支限界法 符号三角形问题

    基本题一:符号三角形问题 一.实验目的与要求 1.掌握符号三角形问题的算法: 2.初步掌握回溯算法: 二.实验题图 下面都是"-".下图是由14个"+"和14个 ...

  3. 符号三角形问题(回溯)

    [cpp] view plaincopy /*回溯法解符号三角形问题 问题描述: 如下图是由14个"+"和14个"-"组成的符号三角形, 2个同号下面都是&qu ...

  4. java 符号三角形_算法java实现--回溯法--符号三角形问题

    符号三角形问题的java实现(回溯法) 具体问题描述以及C/C++实现参见网址 http://blog.csdn.net/liufeng_king/article/details/8764319 /* ...

  5. 算法设计与分析——回溯法——符号三角形问题

    #include<iostream> using namespace std;class Triangle{public:void Backtrack(int t);int n;//第一行 ...

  6. 005-3算法笔记【回溯】符号三角形

    问题 符号三角形的 第1行有n个由"+"和"-"组成的符号 ,以后每行符号比上行少1个,2个同号下面是"+",2个异 号下面是"- ...

  7. 符号三角形问题(Java)

    符号三角形问题(Java) 文章目录 符号三角形问题(Java) 1. 前置介绍 2.算法设计 3.程序代码 4.算法效率 5.参考资料 1. 前置介绍 符号三角形定义 如下图所示,符号三角形是由14 ...

  8. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现

    是使用递归方法实现回溯算法的,在第一次使用二维矩阵的情况下,又做了一次改一维的优化 但是算法效率仍然差强人意,因为使用递归函数的缘故 下面提供另一种回溯算法的实现,使用数据结构"栈" ...

  9. [Leetcode][第81题][JAVA][N皇后问题][回溯算法]

    [问题描述][困难] [解答思路] 1. 主副对角线列 标记 复杂度 import java.util.ArrayDeque; import java.util.ArrayList; import j ...

最新文章

  1. MYSQL执行计划EXPLAIN
  2. HTML简介及常用标签介绍
  3. python socket原理 及socket如何使(tcp udp协议)
  4. 姆町网络验证带壳内存取密钥
  5. SpringCloud服务器服务注册在Euraka上,访问IP地址问题
  6. c编程语言外文翻译及原文,外文翻译--基于ST语言(结构化文本语言)可编程控制器(中文)...
  7. ruhe调整计算机色温,显示器色温怎么调节
  8. Java中修饰变量和方法的关键字总结分析
  9. 正襟危坐说--操作系统(伍):进程间通信
  10. 如何给运行中的docker容器增加映射端口
  11. 如何看待腾讯云电子签呢?
  12. 北斗短报文和北斗定位入门篇
  13. Oracle数据库Timestamp数据差值计算Sql语句
  14. gentoo virtual couldnt download
  15. 讲讲自己一天入门Python的一些心得
  16. 施密特(smit)触发器
  17. 同济大学高等数学上册电子版_函数的凹凸性漫谈|高等数学漫步(二)
  18. CorelDRAWX4的C++插件开发(四十一)纯C++插件开发(5)实现六个纯虚函数
  19. 列车车次查询系统php源码,火车票务系统源代码(含数据库)
  20. java 按钮 事件_Java给按钮添加事件

热门文章

  1. 微带线宽与承受功率的关系
  2. 硬盘模式兼容性问题不难解决,我们将新电脑的主板设置调整为IDE模式,进入操作系统,修改注册表让操作系统和AHCI匹配:
  3. 用Python创作的搜狗输入法刷字数神器(装逼必备)
  4. 【Mysql】MySQL修改用户host的方法整理
  5. 基于uniapp校园帮外卖跑腿快递代拿平台设计【还可发布到小程序和HTML5】
  6. Ubuntu20.04.3 + opengrok1.7.25 + tomcat10.0.14安装
  7. Android版本中蓝牙简介
  8. 如何将D3.js的强交互延续到Python中?
  9. java时间解析错误_java.lang.IllegalArgumentException:解析错误-日期格式错误?
  10. View和XenDesktop到底谁更简单 Part II