符号三角形
符号三角形的 第1行有n个由“+”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”+“,2个异 号下面是”-“ 。计算有多少个不同的符号三角形,使其所含”+“ 和”-“ 的个数相同 。 n=7时的1个符号三角形如下:
+ + - + - + +
+ - - - - +
- + + + -
- + + -
- + -
- -
+
+ + - + - + +
+ - - - - +
- + + + -
- + + -
- + -
- -
+
15 16 19 20 0
15 1896 16 5160 19 32757 20 59984
思路:把-‘-’当作1,‘+’当作0时;这样正好满足题意。
我们知道1^1=0; 1^0=1, 0^1=1 , 0^0=0;
然后可以做异或运算
例如n=3;
第一次是
+++
++
+
第二次改变a[1][n]即a[1][3]=1,即改变成了-号,即;
++-
+-
-
然后a[1][2]每次也是两种状态,回溯后每次逐一遍历。
暴力代码:
AC代码:#include<stdio.h> #include<string.h> int ans[30]; int a[30][30];//用于保存每个n的第一层的状态的中间过程 int count;//记录1的个数 void DFS(int n) { int i,j; if(n>24) return ; for(i=0;i<=1;i++) { a[1][n]=i;//只需要暴力第一行即可(用0表示+号,1表示-号),每次回溯改变一下符号 count+=i; for(j=2;j<=n;j++) { a[j][n-j+1]=a[j-1][n-j+1]^a[j-1][n-j+2]; count+=a[j][n-j+1]; } if(count*2==n*(n+1)/2) //用count表示-号的个数,对比+和-是否相等 ans[n]++; DFS(n+1); //回溯 count-=i;//取消后面的标记 for(j=2;j<=n;j++) { a[j][n-j+1]=a[j-1][n-j+1]^a[j-1][n-j+2]; count-=a[j][n-j+1]; } } } int main() { int i,j,k,n; memset(ans,0,sizeof(ans)); count=0; DFS(1); while(scanf("%d",&n)!=EOF) { if(!n) break; printf("%d\n",ans[n]); } return 0; }
#include<stdio.h> int main() { int n; int a[30]={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}; while(scanf("%d",&n),n) { printf("%d %d\n",n,a[n]); } return 0; }