找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6049|回复: 0
打印 上一主题 下一主题
收起左侧

程序给你演示如何解开九锁连环

[复制链接]
跳转到指定楼层
楼主
ID:76190 发表于 2015-4-5 20:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

       还记得第一次玩九锁连环的时候,是公司的范姐买了一堆开发智力的玩具,当时觉得九锁连环很高级的样子,于是就试拿来玩了。说实话,真的是第一次拿到手玩,以前没接触过。
       那天下午思考着它的规律,终于打它解开了。
       后来想想,既然是那么有规律,可以通过编程,来演示和记录每一步是怎么操作的,后面想学习的人也可以按着每一步来操作学会它。
      
       于是,今晚突然心血来潮,写了个程序来演示怎么解开九锁连环。由于只是心血来潮,只有数据和图片,改天有空再编写做个FLASH动画来更形象演示怎么每一步解开的。同时也会C的源码贴上来,让有兴趣的人一起来交流交流,有做程序手机程序的朋友,也可以把算法移植过去,做个手机演示程序也挺好的。当然,如果这个只是针对9锁的,理论上,你可以通过改程序,把这个做成N锁连环,就只要改个数据改个长度就可以,因为算法用到递归,不管多少连环,反正就是一直递归下去,直到你电脑CPU挂了都可以了。

       先上点图片。
      这个图标就是通过C程序,把每一个打印出来,保存到一个txt文档里,再导入到excel里去的。其中1就是锁着的,0表示锁下来的。




可以看到,解开九锁连环一共需要341步。当然,解下一个环或扣回一个环都算一步。同时,大家也看到,我在程序里或表格里,都注明了哪一步是扣或解开哪一个环。

好了,慢慢理解这个规律了。下面就是上程序了,这个程序是纯粹的C语言,暂时没有优化,不可,至少可以执行,还有我写程序时的注视,如果有兴趣的朋友再进一步交流了。等以后把java的,processing动画,flash也一直移植过去,做成演示动画就更形象了。

//以下变是程序了,可以直接复制拷贝编译
#include "stdio.h"

#define LOCK_NUMBER 4

unsigned char data[LOCK_NUMBER];

unsigned int unlock(int number);//解锁
unsigned int lock(int number);//扣锁
void dis_step(int number);//看是解几个锁的
void dis_step_lock(int number);
int steps=0;

int file_open=0;


FILE *fp;


int main()
{

       
  int i;
  fp=fopen("九锁连环解锁过程.txt","w");
  if(fp==NULL)
  {
          printf("无法打开");
  }

  //先初始化全部锁上
for(i=0;i<LOCK_NUMBER;i++)
{
          data=0x01;
}


  //这里就是解锁了

   //
  //开始解锁
  for(i=LOCK_NUMBER;i>=1;i--)
  {
           unlock(i);
  }

  //解锁完成



  printf("解锁完成\r\n");
  fclose(fp);

return 0;
}





unsigned int unlock(int number)//解锁
{
  int i=0;

   while(data[number-1]==0x01)// 直到把这个锁解了才退出
   {
       
                   if(number>=3)
                   {
                  //先判断前面n-2个是否都解开了
                        for(i=number-2;i>=1;i--)
                        {
                                 if(data[i-1]!=0x00)
                                 {
                                  //如果遇到还没有解开的, 逆回去先解开前n-1第一个还没有解下来的
                                   unlock(i);
                                         
                                 }
                        }
                         if(i==0)
                         {
                                  //说明前面n-2个都解下来了。
                                  // 再判断n-1个是否解下来
                                 if(data[number-2]==0x01)
                                 {
                                         //如果这个没有放下来
                                         // 就可以把n这个锁解下来了
                                         data[number-1]=0;
                                                   dis_step(number);
                                 }
                                 else if(data[number-2]==0x00)
                                 {
                                         // 如果这个已经放下来了,则需要先把这个扣上去,再能解下后面那个
                                         lock(number-1);
                                 }
                         }

                   }

                   else if(number==2)
                   {

                           if(data[0]==0x01)
                           {
                                data[1]=0;//直接把2解下来
                                          dis_step(number);
                           }
                           else if(data[0]==0x00)
                           {
                                        lock(1);
                           }
                   }

                   else if(number==1)
                   {

                                data[0]=0;//直接把1解下来
                                          dis_step(number);
                   }





          }

   return 1;

}

unsigned int lock(int number)//对第n个上锁
{
        //
        //原理,对第n个上锁也是先判断前面n-2个是否都解下来
        // 如果前面第n-2个解下来:  如果第n-1个是扣上去的,则可以直接扣回去
                                   //如果第n-1个是解下来的,则还需要把第n-1个扣回去
        int i;

        while(data[number-1]==0)//一定要锁上才退出
        {
    if(number==1)
        {

                 // 如果是第一个,直接扣上去了
                data[0]=1;
            dis_step_lock(number);

        }
        else if(number==2)
        {

                 //  如果是第二个,则还需要判断第一个是否扣回去
             if(data[0]==0x00)
                 {
            lock(1);
                 }
                 else if(data[0]==0x01)
                 {
                         data[1]=0x01;
                         dis_step_lock(number);

                 }
       
        }

        else if(number>=3)
        {
       

                for(i=number-2;i>=1;i--)
                {
                       
                 if(data[i-1]!=0x00)
                 {
                  //如果遇到还没有解开的, 逆回去先解开前n-1第一个还没有解下来的
                   unlock(i);
                 }                       


                }

                //说明前面n-2个都已经解下来了
                if(i==0)
                {
               
                  //说明前面n-2个都解下来了。
                  // 再判断n-1个是否解下来
                 if(data[number-2]==0x01)
                 {
                         //如果这个没有放下来
                         // 就可以把n这个锁扣去来了
                         data[number-1]=1;
                         dis_step_lock(number);

                 }
                 else if(data[number-2]==0x00)
                 {
             // 如果这个已经放下来了,则需要先把这个扣上去,才能扣下后面那个
                         lock(number-1);
                 }                       

                }




        }

        }

  return 1;

          
}



void dis_step(int number)
{
         int i;
  steps++;

  printf("(unlock)%3d step: %3d ",number,steps);
  fprintf(fp,"unlock %3d step: %3d ",number,steps);

  for(i=0;i<LOCK_NUMBER;i++)
  {
           printf(" %d",data);
           fprintf(fp," %d",data);

  }
  printf("\r\n");
   fprintf(fp,"\r\n");
}

void dis_step_lock(int number)
{
         int i;
  steps++;

  printf("(  lock)%3d step: %3d ",number,steps);
   fprintf(fp ,"  lock %3d step: %3d ",number,steps);

  for(i=0;i<LOCK_NUMBER;i++)
  {
           printf(" %d",data);
                    fprintf(fp," %d",data);
  }
  printf("\r\n");
  fprintf(fp,"\r\n");
}



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表