灯泡排列题

原题出处:  点击打开链接 因为这里面还有更加有意思的题目。



此题发现过程:看别人博客,看到迷宫解法,点入后,见到了此题。当时估计了下自己的电脑和编写程序的能力,觉得大部分可能可以拿下,遂动手。

思考过程总结:这里的限制条件就是最好的帮助缩小可能性的方法。说白了是让读者在1-9里面挑四个不重样的数。概率就是:(1/9)*(1/8)*(1/7)*(1/6)

代码思路评价:用的尾递归解法。

代码瑕疵:有一处至今没有想出为何加上它之后程序反而跑不动了。前面所述问题现已解决。但依然要运行多次后 才能得到谜底:之前是运行20+次,如今运行10+次。

上面那个结果看着很干净是我运行的时候运气好。其实是程序崩溃了十次之后得到的。

附上代码:

<pre name="code" class="cpp">#include<stdio.h>  
#include<stdlib.h>  
#include<time.h>  
   
struct numbers{  
    int apple[5];  
    int boy[4];  
    int cat[3];  
    int dog[2];  
    int egg;  
};  
   
void initializenumbers(struct numbers* good);  
void calculate(struct numbers* good);  
   
int main(){  
  
    struct numbers good;  
    calculate(&good);  
         
   
    return 0;  
}  
   
void initializenumbers(struct numbers* good){  
    int b, c, d, e;  
   
        for (b = 0; b < 4; b++)  
            good->boy[b] = good->apple[b] + good->apple[b + 1];  
        for (c = 0; c < 3; c++)  
            good->cat[c] = good->boy[c] + good->boy[c + 1];  
        for (d = 0; d < 2; d++)  
            good->dog[d] = good->cat[d] + good->cat[d + 1];  
        good->egg = good->dog[0] + good->dog[1];    
  
        for (e = 0; e < 5; e++)  
        printf("%5d", good->apple[e]);  
    printf("\n");  
      
                           
      
}  
  
void calculate(struct numbers* good){  
  
    int i,p;  
    time_t t;  
    srand((unsigned) time(&t));  
  
    if (good->dog[0] == good->cat[2])  
        return;  
  
    else {  
  
       for (i = 0; i < 4; i++){                    //Start to generate the random answer;                  
              
            good->apple[i] = rand()%10;  
                while (good->apple[i] == 0)  
                    good->apple[i] = rand()%10;  
    
               for (p=i-1; p >= 0;p--) {    
              
            if (p == -1)  
                continue;  
                    if(good->apple[p] == good->apple[i]) {   
   
                        good->apple[i]= rand()%10;  
                while (good->apple[i] == 0)  
                    good->apple[i] = rand()%10;  
                            p = i ;    
                    }    
               }   
   
      }
          
        while (good->apple[2] != good->apple[0] + good->apple[1]){    //照理可以加快 却让程序诡异。 
            for (i = 0; i < 4; i++){                    //Start to generate the random answer;                  
              
            good->apple[i] = rand()%10;  
                while (good->apple[i] == 0)  
                    good->apple[i] = rand()%10;  
    
               for (p=i-1; p >= 0;p--) {    
              
            if (p == -1)  
                continue;  
                  if(good->apple[p] == good->apple[i]) {   
                        good->apple[i]= rand()%10;  
                while (good->apple[i] == 0)  
                    good->apple[i] = rand()%10;  
                p = i ;    
                    }    
               }    
        }
                 
      }   
        good->apple[4]=good->apple[0];  
        initializenumbers(good);  
        calculate (good);  
    }  
}


2014-Aug-24: 今天晚上,优化成了各个模块而且前面的思路是有错误的。其实只要小于1/9 * 1/8的概率一百次随机一般能中一次我知足了。改进后程序只要运行一次,但运行时间还是久的。附上代码:

#include<stdio.h>  
#include<stdlib.h>  
#include<time.h>  
   
struct numbers{  
    int apple[5];  
    int boy[4];  
    int cat[3];  
    int dog[2];  
    int egg;  
};  


void make(struct numbers* good);   
void initializenumbers(struct numbers* good);  
void calculate(struct numbers* good);  
int  forapplethree(struct numbers* good);
   
int main(){  
  
    struct numbers good;  
    calculate(&good);  
         
   
    return 0;  
}  

int forapplethree(struct numbers* good){

	int q, flag = 0;

	for (q = 1; q < 10; q++){
		good->apple[3] = q;
		initializenumbers(good);
		if (good->dog[0] == good->cat[2]){
			flag = 1;
			break;
		}
	}
	return flag;

}


void make(struct numbers* good){

    int i,p;  
    time_t t;  
    srand((unsigned) time(&t)); 

    for (i = 0; i < 4; i++){                    //Start to generate the random answer;                  
              
            good->apple[i] = rand()%10;  
                while (good->apple[i] == 0)  
                    good->apple[i] = rand()%10;  
    
               for (p=i-1; p >= 0;p--) {    
              
            if (p == -1)  
                continue;  
                  if(good->apple[p] == good->apple[i]) {   
                        good->apple[i]= rand()%10;  
                while (good->apple[i] == 0)  
                    good->apple[i] = rand()%10;  
                p = i ;    
                    }    
               }    
        }
}

   
void initializenumbers(struct numbers* good){  
    int b, c, d, e;  
   
        for (b = 0; b < 4; b++)  
            good->boy[b] = good->apple[b] + good->apple[b + 1];  
        for (c = 0; c < 3; c++)  
            good->cat[c] = good->boy[c] + good->boy[c + 1];  
        for (d = 0; d < 2; d++)  
            good->dog[d] = good->cat[d] + good->cat[d + 1];  
        good->egg = good->dog[0] + good->dog[1];    
  
        for (e = 0; e < 5; e++)  
        printf("%5d", good->apple[e]);  
    printf("\n");  
      
                           
      
}  
  
void calculate(struct numbers* good){    
  
    if (good->dog[0] == good->cat[2])  
          return;  
  
    else {  
		int ff = 0;
          make (good);
          while (good->apple[2] != good->apple[0] + good->apple[1]) 
    				         make(good);  
          good->apple[4]=good->apple[0];  
          initializenumbers(good);
	  ff = forapplethree (good);
	  if (ff != 1)  
          	calculate (good);
	  else 
		return;
	 
    }  
}


这次程序花了四分钟算出的。公司的电脑。GNW的编译器。

编后说说: 在未知的情况下,个人还是喜欢用随机做这个程序,在对数字不敏感的前提下,担心用for双嵌套循环时间会更久。反正也就十个数随机选两个,电脑还吃得消,多的话此方法确实不提倡,会考虑双嵌套。

 

最后还是想说,如果有高手看见请指教更加好的方法。谢谢!


 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

取啥都被占用

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值