C++搜索與回溯算法之符號三角形

符號三角形


Description

符號三角形的第1行有n個由“+”和”-“組成的符號 ,以後每行符號比上行少1個,2個同號下面是”+“,2個異號下面是”-“ 。計算有多少個不同的符號三角形,使其所含”+“ 和”-“ 的個數相同。
n=7時的1個符號三角形如下:

+ + - + - + +
+ - - - - +
- + + + -
- + + -
- + -
- -
+

Input

每行1個正整數n<=24,n=0退出.

Output

n和符號三角形的個數.

Sample Input

15
16
19
20
0

Sample Output

15 1896
16 5160
19 32757
20 59984

思路

這道題應該用深搜去構造頂層,然後推算出其他的層,在推算的同時進行給其中一種符號的計數,最後判斷該符號的數是不是總符號數的一半,剩下的一些細節(諸如符號總數是否可以整除2、如何在輸入0時結束程序等)我就不解釋了,不過代碼裏的註釋中會有。

解題

#include<iostream>
using namespace std;
int n,total,sum;
int word[30][30];   //存儲符號的數組       
void wxy() //函數名沒有含義
{
    int x=n,y=0; //x用於枚舉層數,y用於計算其它層負號個數
    while(x--) //枚舉層數
        for(int i=1;i<=x;i++)
        {
            word[x][i]=(word[x+1][i]+word[x+1][i+1])%2; //定義第n-x+1層的第i個符號
            if(word[x][i]) y++; //若word[x][i]爲負號,其它層負號個數加1
        }
    if(sum+y==n*(n+1)/2/2) total++; //若負號的個數爲符號總數的一半,情況數加1(運用了等差數列)
}
void dfs(int x)
{
    for(int i=0;i<2;i++) //0爲正號,1爲負號
    {
        if(i) sum++; //給題目中頂層的負號計數
        word[n][x]=i;   //定義頂層的第x個符號是正還是負
        if(x==n) wxy(); //若頂層的所有符號定義完畢,計算其它層的負號個數
        else dfs(x+1); //定義頂層的第x+1個符號
        if(i) sum--; //回溯
    }
}
main()
{
    while(cin>>n&&n) //輸入n,判斷n爲不爲0
    {
        cout<<n<<" ";
        if((n*(n+1)/2)%2) {cout<<"0"<<endl;continue;} //判斷符號總數是否可以整除2,(n*(n+1)/2是運用等差數列來算總數的)
        dfs(1);
        cout<<total<<endl;
        total=sum=0;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章