符号三角形的 第1行有n个由“+”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”+“,2个异 号下面是”-“ 。计算有多少个不同的符号三角形,使其所含”+“ 和”-“ 的个数相同 。 n=7时的1个符号三角形如下:
+ + - + - + +
+ - - - - +
- + + + -
- + + -
- + -
- -
+
+ + - + - + +
+ - - - - +
- + + + -
- + + -
- + -
- -
+
15 16 19 20 0
15 1896 16 5160 19 32757 20 59984
题目n的范围是24,数据范围较小,打表思路。
打表过程主要是针对所有情况的搜索,考验代码能力。
由于每一个n都可以承接n-1的关系,可以从1开始从1,0两个量中选择,然后依次按位dfs下去,这样保证了2^24中求情况都求得,计算过程中,把+ - 看做二进制,通过异或即可得到以后的每一行的情况,根据1个数的统计即可得出是否正确。(注意每次遍历以后交换取值的时候要将上一次的结果减去)
打表与ac代码:
#include<bits/stdc++.h>
using namespace std;
int ans[30];
int sum;
int cnt[30][30];
int res[]= {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 dfs(int n)
{
if(n>24)
return 0;
for(int i = 0; i < 2; ++i)
{
cnt[1][n] = i;
sum+=i;
for(int j = 2; j <= n; ++j)
{
cnt[j][n-j+1] = cnt[j-1][n-j+1]^cnt[j-1][n-j+2];
sum += cnt[j][n-j+1];
}
if(sum*2 == n*(n+1)/2)
ans[n]++;
dfs(n+1);
sum-=i;
for(int j = 2; j <= n; ++j)
{
cnt[j][n-j+1] = cnt[j-1][n-j+1]^cnt[j-1][n-j+2];
sum -= cnt[j][n-j+1];
}
}
}
int main()
{
/*dfs(1);
for(int i = 1; i <= 25; ++i)
{
cout << ans[i] << ", ";
}*/
int n;
while(cin >> n && n != 0)
{
cout << n << " " << res[n] << endl;
}
}