符号三角形问题(回溯法)

来源:互联网 发布:彩票代购软件 编辑:程序博客网 时间:2024/06/14 20:10
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 ;   //删除             }         }    }  }
1 0
原创粉丝点击