HDU 2510 符号三角形 NYOJ491 幸运三角形 (回溯||打表) 代码带解释

本文介绍了一种称为“幸运三角形”的数学问题,探讨了如何通过编程算法来确定特定条件下幸运三角形的数量。提供了两种解决方案:一种是使用深度优先搜索算法进行表格填充,另一种是采用回溯算法直接求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


幸运三角形

时间限制:1000 ms  |  内存限制:65535 KB

难度:3

描述

        话说有这么一个图形,只有两种符号组成(‘+’或者‘-’),图形的最上层有n个符号,往下个数依次减一,形成倒置的金字塔形状,除第一层外(第一层为所有可能情况),每层形状都由上层决定,相邻的符号相同,则下层的符号为‘+’,反之,为‘-’;如下图所示(n = 3 时的两种情况)

                                         

如果图中的两种符号个数相同,那这个三角形就是幸运三角形,如上图中的图(2.

输入

有多组测试数据(少于20组)。
每行含一个整数n0<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];
       }
    }
}


/*

比赛时可以打表过了这道题,但是如果换一种考法,要输出某一行的符号情况,打表就不能用了,深搜肯定超时,强烈建议同学们把第二段回溯的代码看透,多进行一题多解,多题一解的练习。

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值