- /* Backtracking to solve symbolic triangle problems
- Problem Description:
- As a symbolic triangle consisting of 14 "+" and 14 "-", 2 are "+" under the same number, and 2 are "-" below.
- - + + - + + +
- - + - - + +
- - - + - +
- + - - -
- - + +
- - +
- -
- In general, the first line of the symbol triangle has n symbols, and the sign triangle problem requires a given n,
- Calculates how many different symbol triangles have the same number of "+" and "-" contained.
- Problem Solving Ideas:
- 1, constantly change the first line of each symbol, search for a solution that meets the criteria, you can use recursive backtracking
- For ease of operation, set + to 0,-to 1, which allows you to use an XOR operator to represent the relationship of the symbol triangle
- + + is 0^0=0,--for + that is 1^1=0, +--that is, 0^1=1,-+-that is, 1^0=1;
- 2, because the number of two symbols is the same, you can prune the tree,
- When the total number of symbols is odd, there is no solution when a symbol exceeds half of the total
- Refer to the learning materials, re-implementation to practice, there are omissions please correct [email protected].
- Yang Xiaojin, 17:13 2009-8-5
- */
- #include "iostream"
- Using namespace std;
- typedef unsigned char uchar;
- Char cc[2]={' + ','-'}; //Easy to output
- int n, //Total number of first line symbols
- Half, //Total symbols in half
- Counter //1 count, i.e. "-" number count
- Uchar **p; //Symbol storage space
- Long sum; //Meet the criteria for the triangle Count
- T, the first line of the T-symbol
- void BackTrace (int t)
- {
- int I, J;
- if (T > N)
- {//symbol fills complete
- sum++;
- //Print symbols
- cout << "<< sum << " A:/n ";
- For (i=1; i<=n; ++i)
- {
- For (j=1; j<i; ++j)
- {
- cout << "";
- }
- For (j=1; j<=n-i+1; ++j)
- {
- cout << cc[P[i][j]] << "";
- }
- cout << "/n";
- }
- }
- Else
- {
- For (i=0; i<2; ++i)
- {
- P[1][t] = i; //First line of T-symbol
- Counter + = i; //"-" number statistics
- for (j=2; j<=t; ++j) //When the first line of the symbol >=2, you can calculate some of the symbols in the following line
- {
- P[J][T-J+1] = p[j-1][t-j+1]^p[j-1][t-j+2]; //Via XOR or op-downlink symbol
- Counter + = p[j][t-j+1];
- }
- if ((counter <= half) && (t* (t+1)/2-counter <= half))
- {//If the symbol statistics are not more than half, and the other symbol is not more than half
- BackTrace (t+1); //Add the next symbol in the first line
- }
- //backtracking, judging another symbol situation
- For (j=2; j<=t; ++j)
- {
- Counter-= p[j][t-j+1];
- }
- Counter-= i;
- }
- }
- }
- int main ()
- {
- cout << "Please enter the first line of the number of symbols N:";
- CIN >> N;
- Counter = 0;
- sum = 0;
- Half = N (n+1)/2;
- int i=0;
- if (half%2 = = 0)
- {//Total number must be even, if odd, no solution
- 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 Total" << sum << "x" << Endl;
- return 0;
- }
The sign triangle problem of backtracking method