• 符号三角形问题回溯法


    问题描述:

      由14个“+”号和14个“-”号组成的符号三角形。

      2个同号下面是“+”号,2个异号下面是“-”号。

    如图:

      +   +   _   +   _   +   +

          +  _   _   _   _   +

           _   +  +  +  _

            _   +   +  _

             _   +  _

              _  _

                 +

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

    算法设计:

      1 x[i] =1 时,符号三角形的第一行的第i个符号为+

      2 x[i] =0时,表示符号三角形的第一行的第i个符号位-

          共有i(i+1)/2个符号组成的符号三角形。

      3 确定x[i+1]的值后,只要在前面确定的符号三角形的右边加一条边就扩展为x[1:i+1]所相应的符号三角形。

      4 最后三角形中包含的“+”“-”的个数都为i(i+1)/4,因此搜索时,个数不能超过...若超直接可以剪去分枝。

      5 当给定的n(n+1)/2为奇数时,也不符合三角形要求。

    算法描述:

    class Triangle
    {
        friend int Compute(int);
    private:
        void Backtrack(int t);
        int half,
            count,
            **p
        long sum;
    };
    void Backtrack(int t)
    {
        if((count > half) || (t*(t+1)/2-count>half))
            return;
        if(t>n)
            sum++;
        else
        {
            for(int i=0;i<2;j++)
            {
                p[1][t] = i;
                count+=i;
                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;
            }
        }
    }
    int Compute(int n)
    {
        Triangle X;
        X.n = n;
        X.count = 0;
        X.sum = 0;
        X.half = n*(n+1)/2;
        if(X.half%2 == 1)
            return 0;
        X.half = X.half/2;
        int * * p = new int * [n+1];
        for(int i=0;i<=n;i++)
            p[i] = new int [n+1];
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
                p[i][j] = 0;
        X.p = p;
        X.Backtrack(1);
        return X.sum;
    }

    算法实例:

    #include <stdio.h>
    #include <conio.h>
    #define MAX 100
    
    //global variables
    int count=0;//the number of '-'
    int sum=0;//the number of the result
    int p[MAX][MAX]={0};       //1 is '-'  0 is '+'
    int n=0;
    int half=0;//half=n*(n+1)/4
    
    void back_triangle(int t);
    
    int main()
    {
        printf("Please input n:");    
        scanf("%d",&n);
        half=n*(n+1)/2;
        if(half%2!=0)
        {
            printf("The number that you input is not meaningful for this problem!");    
            getch();
            return 1;
        }
        half/=2;
        back_triangle(1);    
        printf("The result is %d",sum);
        getch();
        return 0;
    }
    
    void back_triangle(int t)
    {
        if(count>half || t*(t-1)/2-count>half)//because of this,the "count==half" is not necessary
            return ;    
        if(t>n)   //the count==half is not necessary
        {
            sum++;
            for(int temp=1;temp<=n;temp++)
            {
                for(int tp=1;tp<=n;tp++)
                {
                    printf("%d ",p[temp][tp]);    
                }    
                printf("\n");
            }
            printf("\n");
        }
        else
        {
            int i;
            for(i=0;i<2;i++)
            {
                p[1][t]=i;
                count+=i;
                int j;
                for(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];
                }
    
                back_triangle(t+1);
    
                for(j=2;j<=t;j++)
                    count-=p[j][t-j+1];
                count-=i;
            }
        }
    }

    运行结果:

  • 相关阅读:
    Eclipse解决Ctrl+c很卡的方法
    关于编程,大学没有传授的十件事-月光博客
    最牛B的编码套路
    (CareerCup)find the largest repetitive sequence
    (CareerCup)Find next higher number with same digits
    2013年HTML5峰会 一场守望者的盛宴
    Youzi2D推出开源HTML5游戏加速引擎
    HTML5与原生APP之争胜负已出?
    编程的未来
    拖拽即可创建HTML5网站的建站平台
  • 原文地址:https://www.cnblogs.com/xing901022/p/2735058.html
Copyright © 2020-2023  润新知