符号三角形问题
右图所示的三角形中,有14个“+“和14个“-”。2个同号下面是+,两个异号下面是-。
在一般情况下,符号三角形的第一行有n个符号。符号三角形问题,要求对于给定的n,计算有多少个不同的符号三角形,使其所含的“+”和“-”相同。
解:
首先要求产生的‘+’与‘-’的数量一样多,所以当给定的n不能满足(n+1)*n%4==0的话一定不能构成符号三角形
其次明确三角形的产生情况取决于第一行的‘+’、‘-’号的情况
所以在解决此题的过程中需要进行第一行的构造,以此产生后面几行的结果
构造第一行的过程中,从第一个到最后一个依次构造
此时使用p[][]来保存三角形,当p[i][j]=1时代表此处为‘+’号,反之亦然
在构造三角形的过程中将‘+’号的数量进行统计(因为p[i][j]为0,1所以直接加上就可以)。
在构造第一行的过程中是通过每次添加一位来进行,当第一行 添加一位的时候,
整个三角形就会 添加一行,而且剩余的几行都会添加一位
因此回溯的传递参数代表了第一行此时要构造的下标从0开始,n-1为最后一位。
当t==n时所有构造完成即到达解空间。
#include <stdio.h>
int n;
int half,count,sum;
int p[100][100];
void dfs(int t)
{
if(t==n)
{//到达解空间时进行判断‘+’号的数量是否为一半
if(count==half)
sum++;
return;
}
//当没有达到最后一位时
for(int i=0;i<2;i++)
{//可以放在第一行第t位的有两种情况,0或者1
p[0][t]=i;
//count统计‘+’号出现的次数
count+=i;
for(int j=1;j<=t;j++)
{
//利用第一层添加的第t位为下面的几行添加一位
//以此构建出整个三角形
p[j][t-j]=p[j-1][t-j]^p[j-1][t-j+1];
count+=p[j][t-j];
}
if(count<=half&&(t+1)*(t+2)/2-count<=half)
//满足条件的时候进行第一行下一位即第t+1位的构造
dfs(t+1);
for(int j=1;j<=t;j++)
count-=p[j][t-j];
count-=i;
}
}
int main()
{
scanf("%d",&n);
if(n*(n+1)%4)
printf("no\n");
else{
half=n*(n+1)/4;
count=0;
sum=0;
dfs(0);
printf("%d\n",sum);
}
return 0;
}