import java.util.Scanner;
/** * 题:符号三角形问题 * 给定第一行的符号个数,符号只能为+或者 - 问+ 和 - 个数相同的方案有多少种 * example: * ++- * +- * - * 利用回溯法 。当其中一种个数大于一半时 ,不进行下层计算。即剪枝 * 注:二维数组的0列都不要,从第一行,第一列开始算 * * */
public class Triangle {
public static int [][] p ; //三角形数组
public static int count = 0 ; // + 为 0 , - 为 1 ,记 -个数
public static int half; // n*(n+1)/4
public static int n; // 第一行符号的个数
public static int sum; // 已找到符号三角形的个数
public static void main(String args[])
{
p = new int[100][100];
System.out.println("输入第一行符号的个数;");
Scanner sc = new Scanner(System.in);
n =sc.nextInt() ;
half = n*(n+1)/4; //+ 号个数 或者 -号的个数
if( n*(n+1)/2 == 1 ) //+- 号至和等于 奇数 不可能
System.out.println("无解 ");
Backtrack(1); //从第一列开始算
System.out.println(sum);
}
private static void Backtrack(int t) {
if(count > half || t*(t-1)/2-count > half ) return; //减号的个数或者加号的个数大于一半,退出
if(t > n ) //符合要求 sum++;
{
sum ++;
for(int i = 1 ; i <= n ; i ++) //打印
{
for(int j = 1 ; j <= n ; j ++)
System.out.print(p[i][j]);
System.out.println();
}
System.out.println("-------------------");
}
else
{
for(int i = 0 ; i < 2 ; i ++)
{
p[1][t] = i;
count += i ; //记住减号的个数,因为加号为零
for(int j = 2 ; j <= t ; j ++) //假如符号的个数大于2,可以求接下来的符号
{
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 ; //删除
}
}
}
}
符号三角形问题(回溯法)
原文作者:回溯法
原文地址: https://blog.csdn.net/sinat_26046027/article/details/53172195
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/sinat_26046027/article/details/53172195
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。