把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

OpenJudge 2.5-2990 符号三角形

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


      思路简析:

       这道题我用了两个函数,一个用来深搜(其实也就离一般的递归不远了),推出首层所有可能的情况,到达边界(推完之后)就调用另一个函数推整个三角形(类似构图的思想,但不用构图,计算正号或负号的个数,再判断是否是整个三角形的一半就可以了)。至于具体制图过程,在代码中有详细注释(详细看代码)。另外注意一点,输入n的时候就可以判断整个三角形的符号个数是否能被2整除,如果不能,则不能达到分成正号等于负号的情况,就直接按格式输出0。还有一点,此题容易超时,能省则省。

        代码实现:

#include<cstdio>
#include<cstring>
int a[25][25],n,sum;
void f()
{
	int i,j,s=0;
	for(i=0;i<n;i++)//第一层的负号数量
		s+=a[0][i];
	for(i=1;i<n;i++)//2...n层
		for(j=0;j<n-i;j++)//n行就有n-i+1个符号
		{
			a[i][j]=(a[i-1][j]+a[i-1][j+1])%2;//上方两个异号 
			/*
			① 1 1 同负 结果:1
			② 0 0 同正 结果:0
			③ 1 0 一正一负 结果:0
			综上所述,只有同负才为1,才会标记a[i][j]为负
			*/ 
			s+=a[i][j];//负号个数+1
		}
	if(s==n*(n+1)/2/2)//如果负号个数是符号个数的一半
		sum++;
}
void dfs(int c)
{
	if(c==n)
	{
		f();
		return ;
	}
	else
	{
		for(int i=0;i<2;i++)//0表示加号,1表示负号
		{ 
			a[0][c]=i;
			dfs(c+1);
		}
	}
}
int main()
{
	while(scanf("%d",&n)&&n!=0)
	{
		sum=0;
		if(n*(n+1)/2%2!=0)
			printf("%d 0\n",n);
		else
		{
			dfs(0);
			printf("%d %d\n",n,sum);
		}
	}
}


posted @ 2017-07-12 11:56  Starlight_Glimmer  阅读(35)  评论(0编辑  收藏  举报  来源
浏览器标题切换
浏览器标题切换end