题目描述:
在符号三角形中,有14个“+“和14个“-”。2个同号下面是+,两个异号下面是-。 在一般情况下,符号三角形的第一行有n个符号。符号三角形问题,要求对于给定的n,计算有多少个不同的符号三角形,使其所含的“+”和“-”相同。
题目类型:暴力算法、回溯算法
0、1暴力算法代码如下:
/*
二进制将第一行确定,再由a[i][j]=a[i-1][j]^a[i-1][j+1]依次确定每一行
无需单独统计0和1,sum一个值即可确定
*/
#include<stdio.h>
#include<math.h>
int main()
{
int i,j,n,num,temp,max;
int a[100][100]={0};
int sum=0,count=0;
scanf("%d",&n);
max=n*(n+1)/2;
if(max%2!=0) {
printf("error!\n");
return 0;
}
for(num=0;num<=pow(2,n);num++) {
temp=num;
sum=0;
for(i=0;i<n;i++) { //先将第一行确定
a[0][i]=temp%2;
temp/=2;
sum+=a[0][i];
}
for(i=1;i<n;i++) { //依次确定下面的每一行的第j列数字
for(j=0;j<n-i;j++) {
a[i][j]=a[i-1][j]^a[i-1][j+1];
sum+=a[i][j];
}
if(sum>max/2) { //如果大于一半,则不需要继续往下走
break;
}
}
if(sum==max/2) {
count++;
}
}
printf("%d\n",count);
return 0;
}
回溯算法代码如下:
/*
traceback(int col)中,col控制的是第一行的列元素
依次确定第一行的每一个数字,确定完一个之后,依次生成该数字对应的一个斜行
*/
#include<stdio.h>
int n;
int count=0,sum=0;
int a[100][100]={0};
int half;
char c[2]={'+','-'};
void traceback(int col)
{
int i,j,k;
if(col==n) {
count++;
for(i=0;i<n;i++) {
for(j=0;j<n-i;j++) {
printf("%c",c[a[i][j]]);
}
printf("\n");
}
return ;
}
for(k=0;k<2;k++) {//利用for循环控制k值在0和1之间的变换
a[0][col]=k;
sum+=k;
for(i=1;i<=col;i++) {
a[i][col-i]=a[i-1][col-i]^a[i-1][col-i+1];
sum+=a[i][col-i];
}
if(sum<=half/2 && (col+1)*(col+2)/2-sum<=half/2) {//1和0的个数要小于等于一半才能col+1
traceback(col+1);
}
for(i=1;i<=col;i++) {
sum-=a[i][col-i];
}
sum-=k;
}
}
int main()
{
scanf("%d",&n);
half=n*(n+1)/2;
if(half%2!=0) {
printf("not have.\n");
return 0;
}
traceback(0);
printf("%d\n",count);
return 0;
}