芯片测试

(1)蛮力算法

1)问题:假设条件:有n片芯片,已知其中好的芯片比坏的芯片至少多1片。
问题要求:通过测试从中找出1片好芯片。
测试方法:将2片芯片放到测试台上,2片芯片相互测试并报告测试结果,
“好”或者“坏”。假定好芯片的报告是正确的,坏芯片的报告
是不可靠的(可能是对的,也可能是错的)。
设计算法:使用最少的测试次数找出1片好芯片。
2)解析:任取一片和n-1测试,如果n/2(向下取整)结果是好的,这一片是好的。
3)设计:

#include<iostream>
#include<cmath>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <cstring>
#define MAX 100
using namespace std;

int main(){
    int n;
    int a[MAX];
    while(cin>>n){
        srand(time(NULL));
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++){   /*芯片编号为数组下标,从1开始*/
             cin>>a[i];             /*数组值代表芯片好坏,1为真0为假*/
        }
        int cnt=0;                  /*查找次数*/
        for(int i=1;i<=n;i++){
            int sum=0;
            for(int j=1;j<=n;j++){
                cnt++;
                if(i!=j&&a[i]==1&&a[j]==1)   /*两片芯片都是好的*/
                    sum++;
                    if(i!=j&&a[i]==1&&a[j]==0)   /*测试芯片是坏的*/
                        sum+=rand()%2;
                    if(i!=j&&a[i]==0&&a[j]==0)   /*两片芯片都是坏的*/
                        sum+=rand()%2;
                }
                if(sum>=n/2){
                    cout<<"查找次数:"<<cnt<<endl;
                    break;
                }
            }
        }
        return 0;
}

4)分析:
最好情况:第一个测试的芯片就是好的,则只需要测试n-1次,时间复杂度为O(n);
最坏情况:第n/2(向下取整)个测试芯片是好的,则需要测试(n-1)*(n/2)次,时间复杂度为O(nlogn);
平均情况:第一个好的芯片出现的可能从1到n/2(向下取整)是一样的,
每个芯片的测试次数都是n-1次,时间复杂度为O(nlogn)。

(2)分治算法

1)问题:同上。
2)解析:将芯片两两分组进行比较,如果测试结果都是好的,则保留任意一块芯片,否则两片芯片都舍弃。如果芯片块数为奇数,则未分组的那块直接保留。将保留的芯片继续两两分组比较,按照同样的规则取舍,直到只剩下一块芯片或者两块芯片。因为题目已经保证好的芯片比坏的芯片至少多一片,每次我们舍弃的都是一好一坏,或者舍弃一块好的保留一块好的,或者舍弃一块坏的保留一块坏的,始终保证了好的芯片至少比坏的芯片多一片,所以最后剩下的一块或者两块芯片就是好的。

3)设计:

  #include<iostream>
  #include <cmath>
  #include <stdio.h>
  #include <time.h>
  #include <stdlib.h>
  #include <cstring>
  #define MAX 100
  using namespace std;

  int main(){
      int n;
      int num1,num2,sum;
      int a[MAX],b[MAX];
      while(cin>>n){            
          srand(time(NULL));
          memset(a,0,sizeof(a));
          memset(b,0,sizeof(b));
          /*a数组标记芯片好坏,b数组记录被保留芯片编号*/
          for(int i=1;i<=n;i++){                    
              cin>>a[i];
              b[i]=i;
          }
          num1=n;
          num2=1;
          sum=0; 
          while(1){
              /*芯片只剩一片或两片则可以直接得到结果,结束循环*/
              if(num1<=2)                   
                  break;
              else if(num1%2){     /*芯片个数为奇数*/
                  for(int i=1;i<num1;i+=2){
                      sum++;            /*记录查找次数*/
                      if(a[b[i]]==1&&a[b[i+1]]==1)   /*两片芯片都是好的*/
                          b[num2++]=b[i+rand()%2];
                      /*两片芯片是坏的,rand模拟结果是好的这一随机现象*/
                      if(a[b[i]]==0&&a[b[i+1]]==0&&rand()%2)                                               
                        b[num2++]=b[i+rand()%2];
                    }
                    b[num2++]=b[num1];      /*最后一块芯片保留*/
               }
               else{                      /*芯片个数为偶数*/
                   for(int i=1;i<=num1;i+=2){
                      sum++;
                      if(a[b[i]]==1&&a[b[i+1]]==1)   /*两片芯片都是好的*/
                          b[num2++]=b[i+rand()%2];
                      if(a[b[i]]==0&&a[b[i+1]]==0&&rand()%2)  /*两片芯片是坏的*/
                         b[num2++]=b[i+rand()%2];
                    }
               }
               num1=num2-1;     /*一次比较后保留芯片的个数*/
               num2=1;          /*下一次查找的开始位置*/
          }
          cout<<"查找次数:"<<sum<<endl; 
          cout<<"找到的芯片编号:"<<b[1]<<endl; 
      }
      return 0;
  }

4)分析:最好情况:当每次测试都是好坏芯片相互测试时,只需要测n/2次就可以找
出好的芯片,时间复杂度为O(logn);
最坏情况:全部都是好的芯片,则需要测试n/2+n/4+......+1次才能找出好的
芯片,时间复杂度为O(n);
平均情况:每次查找的时候通常都是有好有坏,每次的测试次数都小于
n/(2^k)(k为第几轮测试,0<k<=logn),所以时间复杂度为O(logn).

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容