2018年蓝桥杯C/C++组B组第二题

学校组织的软件创意大赛在10号就要截止了。我报了一个项目,就是计算器。
上周学校大创中心组织了一场宣讲,我听了一下,有一点就是说要给自己的作品写说明书,不能是简单的一两百字。
这段时间我给它写了一个说明书,简简单单,写了将近两千字,可能还要写下去。
我是大一的学生,近来突发奇想,想每天做一个蓝桥杯的题目,发现这是不可能的,前面做了第一题,不算难,做这个第二题的时候,突然感受到了无比的压力,做事做出来了,但是花费的时间超过四个小时(这是一场蓝桥杯考试的时间),所以目前来说这个想法算是不行了,还是先想办法学会这若干种排序算法再说吧。
针对这个问题为什么不能快速的写出来,简单来说就是我还没有掌握递归方法的使用,没有了解到递归的重要性。后来还是想办法用了其他方法。
我先把问题粘贴出来:
2.标题:激光样式
x星球的盛大节日为增加气氛,用30台机光器一字排开,向太空中打出光柱。
安装调试的时候才发现,不知什么原因,相邻的两台激光器不能同时打开!
国王很想知道,在目前这种bug存在的情况下,一共能打出多少种激光效果?
显然,如果只有3台机器,一共可以成5种样式,即:
全都关上(sorry, 此时无声胜有声,这也算一种)
开一台,共3种
开两台,只1种
30台就不好算了,国王只好请你帮忙了。
下面是我的解决问题的代码:



#include<stdio.h>

#include<Windows.h>

 

int a[30] = { 0 };

 

int fun1(int num)

{

    int sum = 0;

    int last = 29;

    for (;;)

    {

         //找到最后一个1

         for (int j = last;; j--)

         {

             if (a[j] == 1)

             {

                  last = j;

                  break;

             }

         }

         for (int j = last;;)

         {

             //显示当前排列方式

             /*for (int ss = 0; ss < 30; ss++)

             {

                  printf("%-2d",
a[ss]);

             }

             printf("\n");

             if (GetAsyncKeyState(48))

             {

                  system("pause");

             }*/

             sum++;

             if (j == 29)

             {

                  int goto1 = 0;

                  //go解释:0未找到,1找到一个1,2找到两个1或者唯一一个1前有两个0

                  for (int k = 27, go = 0;;k--)

                  {

                      if (k < 0)

                      {

                          return sum;

                      }

                      if (go == 0)

                      {

                          if (a[k] == 1)

                          {

                               go = 1;

                          }

                          if (k == 27 &&
a[k] == 0)

                          {

                               go = 2;

                          }

                      }

                      else if (go == 1)

                      {

                          k--;

                          if (a[k] == 0)

                          {

                               go = 2;

                          }

                      }

                      else if (go == 2)

                      {

                          if (a[k] == 1)

                          {

                               for (int m = k;; k--)

                               {

                                   if (a[m] == 1)

                                   {

                                       int num1 = 0;

                                       //把下面还有多少个1统计出来,并将1归零

                                       for (int n = m; n < 30;
n++)

                                       {

                                            if (a[n] == 1)

                                            {

                                                a[n]
= 0;

                                                num1++;

                                            }

                                       }

                                       //把剩余的1重新排列

                                       for (int n = m + 1;; n += 2)

                                       {

                                            if (num1 == 0)

                                            {

                                                for (int o = 29; o >= 0;
o--)

                                                {

                                                     if (a[o] == 1)

                                                     {

                                                         last
= o;

                                                         break;

                                                     }

                                                }

                                                break;

                                            }

                                            num1--;

                                            a[n]
= 1;

                                       }

                                       goto1 =
1;

                                       break;

                                   }

                               }

                               if (goto1 == 1)

                               {

                                   goto1 = 0;

                                   break;

                               }

                          }

                      }

                  }

 

                  break;

             }

             else if (j != 29)

             {

                  a[j + 1] = 1;

                  a[j] = 0;

                  j++;

             }

         }

    }

}

 

int main()

{

    int num = 1;

    for (int i = 1; i <= 15; i++)

    {

         //把数组归零

         for (int j = 0; j < 30; j++)

         {

             a[j] = 0;

         }

         //数组赋初值

         for (int j = 0, num1 = i;; j += 2)

         {

             a[j] = 1;

             num1--;

             if (num1 == 0)

             {

                  num += fun1(i);

                  break;

             }

         }

    }

 

    printf("%d", num);

    getchar();

 

    return 0;

}

 


不得不说,我的这个过程是非常差劲的,如果会递归的话过程就会非常简单了。
下面我把从网上看到的一个博客网址贴出来,他的就非常简单了:https://blog.csdn.net/hzj1998/article/details/80492044
我也要好好学学汉诺塔问题的解决方法(即递归)了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值