符号三角形(搜索+递推)

符号三角形
总时间限制: 1000ms 内存限制: 65536kB
描述
符号三角形的第1行有n个由“+”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”+“,2个异号下面是”-“ 。计算有多少个不同的符号三角形,使其所含”+“ 和”-“ 的个数相同。

n=7时的1个符号三角形如下:
+ + - + - + +
+ - - - - +
- + + + -
- + + -
- + -
- -
+
输入
每行1个正整数n<=24,n=0退出.
输出
n和符号三角形的个数.
样例输入

15
16
19
20
0

样例输出

15 1896
16 5160
19 32757
20 59984

思路点拔:本题虽然看上去是符号三角形,但本题不需要输出,所以不妨让1代
表,所以,先搜索出第一行,然后弄出整个三角形,最后比较三角形中加减号的
个数,如果相等,总方案数就加1,本题就结束了~

#include<cstdio>
#include<cstring>
int a[30][30],ans,n;
void sjx()
{
    int totz=0,totf=0;
    for(int i=1;i<=n;i++) //统计第一行的加减号的个数
    {
        totz+=a[1][i];
        totf+=!a[1][i];
    }
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=n-i+1;j++) 
        {
        //注意:^号是指在二进制中,相同的就返回1,不相等的就返回0,
            a[i][j]=a[i-1][j]^a[i-1][j+1];//弄出整个字符三角形
            totz+=a[i][j];
            totf+=!a[i][j];//统计整个三角形中的加减号的个数
        }
    }
    if(totz==totf) //如果
        ans++;
}
void dfs(int index)
{
    if(index==n+1) //设定递归出口
    {
        sjx();
    }
    else
    {
        a[1][index]=1; //搜索出第一行的加号
        dfs(index+1);
        a[1][index]=0;//搜索出第一行的减号
        dfs(index+1);
    }
}
int main()
{
    while(scanf("%d",&n)) //无限输入
    {
        if(n==0) return 0;
        dfs(1); //搜索
        if(n*(n+1)%4==1) //简单剪枝
        {
            printf("%d 0\n",n);
            continue;
        }
        else
        {
            printf("%d %d\n",n,ans); //输出总数
        }
        ans=0;//注意:每次ans都要清0,数组要清空
        memset(a,0,sizeof(a));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42995099/article/details/81806216