回溯法解符号三角形问题

 

 

/*回溯法解符号三角形问题 问题描述: 如下图是由14个“+”和14个“-”组成的符号三角形, 2个同号下面都是“+”,2个异号下面都是“-”。 - + + - + + + - + - - + + - - + - + + - - - - + + - + - 在一般情况下,符号三角形的第一行有n个符号, 符号三角形问题要求对于给定的n, 计算有多少个不同的符号三角形,使其所含的“+”和“-”的个数相同。 解题思路: 1、不断改变第一行每个符号,搜索符合条件的解,可以使用递归回溯 为了便于运算,设+ 为0,- 为1,这样可以使用异或运算符表示符号三角形的关系 ++为+即0^0=0, --为+即1^1=0, +-为-即0^1=1, -+为-即1^0=1; 2、因为两种符号个数相同,可以对题解树剪枝, 当所有符号总数为奇数时无解,当某种符号超过总数一半时无解 参考了学习资料,重新实现以练习,有疏漏之处敬请指正[email protected]。 杨小进,17:13 2009-8-5 */ #include"iostream" using namespace std; typedef unsigned char uchar; char cc[2]={'+','-'}; //便于输出 int n, //第一行符号总数 half, //全部符号总数一半 counter; //1计数,即“-”号计数 uchar **p; //符号存储空间 long sum; //符合条件的三角形计数 //t,第一行第t个符号 void Backtrace(int t) { int i, j; if( t > n ) {//符号填充完毕 sum++; //打印符号 cout << "第" << sum << "个:/n"; for(i=1; i<=n; ++i) { for(j=1; j=2时,可以运算出下面行的某些符号 { p[j][t-j+1] = p[j-1][t-j+1]^p[j-1][t-j+2];//通过异或运算下行符号 counter += p[j][t-j+1]; } if( (counter <= half) && ( t*(t+1)/2 - counter <= half) ) {//若符号统计未超过半数,并且另一种符号也未超过半数 Backtrace(t+1); //在第一行增加下一个符号 } //回溯,判断另一种符号情况 for(j=2; j<=t; ++j) { counter -= p[j][t-j+1]; } counter -= i; } } } int main() { cout << "请输入第一行符号个数n:"; cin >> n; counter = 0; sum = 0; half = n*(n+1)/2; int i=0; if( half%2 == 0 ) {//总数须为偶数,若为奇数则无解 half /= 2; p = new uchar *[n+1]; for(i=0; i<=n; ++i) { p[i] = new uchar[n+1]; memset(p[i], 0, sizeof(uchar)*(n+1)); } Backtrace(1); for(i=0; i<=n; ++i) { delete[] p[i]; } delete[] p; } cout << "/n总共 " << sum << " 个"<< endl; return 0; }

你可能感兴趣的:(算法)