符号三角形问题
下图是由14个“+”和14个“-”组成的符号三角形。2个同号下面都是“+”,2个异号下面都是“-”。
在一般情况下,符号三角形的第一行有n个符号。符号三角形问题要求对于给定的n,计算有多少个不同的符号三角形,使其所含的“+”和“-”的个数相同。
•解向量:用n元组x[1:n]表示符号三角形的第一行。
•可行性约束函数:当前符号三角形所包含的“+”个数与“-”个数均不超过n*(n+1)/4
•无解的判断:n*(n+1)/2为奇数
//符号三角形问题
#include <iostream>
using namespace std;
static const char ch[2] = {'+','-'};
class Triangle
{
friend int Compute(int);
private:
void Backtrack(int t);
int n, //第一行的符号个数
half, //n*(n+1)/4
count, //当前"+"号个数
**p; //符号三角形矩阵
long sum; //已找到的符号三角形数
};
void Output(int n,int **p) //输出符号三角形
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j < i; j++)
{
cout<<" ";
}
for(int j = 1; j <= n-i+1; j++)
{
cout<<ch[p[i][j]]<<" ";
}
cout<<endl;
}
}
void Triangle::Backtrack(int t)
{
if((count > half) || (t*(t-1)/2 - count > half))
{
return ;
}
if(t > n)
{
sum++;
static int temp = 0;
cout<<"第"<<++temp<<"个符号三角形"<<endl;
Output(n,p);
} else {
for(int i = 0; i < 2; i++)
{
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;
}
int main()
{
int n,m;
cout<<"请输入第一行符号个数n,[n*(n+1)]整除4:"<<endl;
cin>>n;
m = Compute(n);
cout<<"这样的符号三角形有"<<m<<"个"<<endl;
return 0;
}