幸运三角形
时间限制:1000 ms | 内存限制:65535 KB
难度:3
描述
话说有这么一个图形,只有两种符号组成(‘+’或者‘-’),图形的最上层有n个符号,往下个数依次减一,形成倒置的金字塔形状,除第一层外(第一层为所有可能情况),每层形状都由上层决定,相邻的符号相同,则下层的符号为‘+’,反之,为‘-’;如下图所示(n = 3 时的两种情况):
如果图中的两种符号个数相同,那这个三角形就是幸运三角形,如上图中的图(2).
输入
有多组测试数据(少于20组)。
每行含一个整数n(0<n<20)。
输出
输出相应的幸运三角形个数。
样例输入
3
4
样例输出
4
6
// 用于打表的简单深搜
# include <stdio.h>
# include <string.h>
int a[50];
int n;
int total;
int jishu;
int main()
{
voiddfs(int step);
while( ~scanf("%d",&n) )
{
memset(a,0,sizeof(a));
jishu=0;
total=n*(n+1)/2;
if(total%2==1)
{printf("0\n");continue;}
dfs(0);
printf("%d\n",jishu);
}
return0;
}
void dfs(int step)
{
void judge ();
if(step==n)
{judge();return;}
a[step]=1;
dfs(step+1);
a[step]=0;
dfs(step+1);
}
void judge()
{
intt1=0,t2=0;
intnn=n;
while(nn>0)
{
for(inti=0;i<nn;i++)
{
if(a[i]==1)
t1++;
else
t2++;
if(t1>total/2||t2>total/2)
break;
}
nn--;
for(inti=0;i<nn;i++)
{
if(a[i]==a[i+1])
a[i]=1;
else
a[i]=0;
}
}
if(t1==t2)
jishu++;
}
// 不用打表都可以过的回溯
# include <stdio.h>
int arr[25][25];
//int ans[25];
int ans[25];
int count;
int main()
{
void dfs(int step);
dfs(1);
int nn;
while( ~scanf("%d",&nn) )
{
//for(int i=1;i<20;i++)
printf("%d\n",ans[nn]);
}
return 0;
}
void dfs(int step)
{
if(step>=22)
return;
for(int i=0;i<=1;i++) // 一开始全为+号
{
arr[1][step]=i;
count+=arr[1][step]; //统计‘-’号的个数
for(int j=2;j<=step;j++)
{// ‘-’用1代替 ‘+’ 用 0 代替
arr[j][step-j+1]=arr[j-1][step-j+1]^arr[j-1][step-j+2];
//根据第i行就可以推出来第i+1行
count+=arr[j][step-j+1];
}
if( count*2==step*(step+1)/2 ) // A
ans[step]++;
dfs(step+1);//回溯补全 //B A和B位置不能互换,想想为什么
count-=arr[1][step];
for(int j=2;j<=step;j++)
{
count-=arr[j][step-j+1];
}
}
}
/*
比赛时可以打表过了这道题,但是如果换一种考法,要输出某一行的符号情况,打表就不能用了,深搜肯定超时,强烈建议同学们把第二段回溯的代码看透,多进行一题多解,多题一解的练习。
*/