Problem 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個同號下面是‘+’,2個異 號下面是‘-’”,類似於位運算中的異或。
直接用‘+’,‘-’來進行計算,多少有點麻煩,所以選擇用 0 代表 ‘+’ , 用 1 代表 ‘-’ 。
本題主要涉及的內容主要是 位運算相關知識 ,講解 位運算。
代碼:
//位運算
//兩位相同則爲 0 , 不同爲 1。
//n <= 24 , 打表
#include <cstdio>
using namespace std;
//求取過程
int ans[30] ;
int a[30];
int main(){
int n , i , j , k ;
for(i = 1 ; i <=24 ; i ++){ // n 總共有 24 種情況
//遍歷 n = 1 ~ 24 的各種情況 , 其中每種情況下也分爲2^n中不同的取值情況
a[1] = (1 << i) - 1; //最大值
while(a[1] >= 0){ //依次遍歷 2^n種情況
for( j = 2 ; j <= i ; j ++){ //求出 n-1 到 1 層的取值情況
a[j] = 0;
for(k = 0 ; k < i - j + 1 ; k ++) // i-j+1表示當前該層的數字的個數
// k 表示當前求取的數所在的位
a[j] = a[j] | ( (a[j-1]>>k)&1 ^ (a[j-1]>>k+1)&1 ) << k; //從後向前求取
}
int ans1 = 0 , ans2 = 0;
for(j = 1 ; j <= i ; j ++){ //統計個數
for(k = 0 ; k < i - j + 1 ; k ++){
if((a[j] >> k)&1) //爲 0;
ans1 ++;
else
ans2 ++;
}
}
if(ans1 == ans2)
ans[i] ++;
a[1] --;
}
printf("%d ",ans[i]);
}
return 0;
}
運行結果:
注:直接提交上述代碼肯定是會超時的 , 所以直接把上述代碼的結果保存在一個結果數組裏面,以下爲AC代碼 。
AC代碼
int ans[25] = {0 , 0 , 0 , 4 , 6 , 0 , 0 , 12 , 40 , 0 , 0 , 171 , 410 , 0 , 0 , 1896 , 5160 , 0 , 0 , 32757 , 59984 , 0 , 0 , 431095 , 822229};
int main(){
int n;
while(scanf("%d" , &n) != EOF && n){
printf("%d %d\n",n , ans[n]);
}
return 0;
}