有n片芯片,已知好芯片比坏芯片至少多1片。现在需要通过测试从中找出1片好芯片,测试方法如下:将2片芯片放到测试台上,2片芯片互相测试并报告测试结果(即好或者坏);其中,好芯片的报告是正确的,而坏芯片的报告是不可靠的。请在上述背景下解决下述问题,
根据好芯片至少比坏芯片多一片的条件,可以得出,在芯片数量大于3片的时候,通过将芯片互检的结果为一好一坏或者两个坏(其中必有至少一个坏芯片)那组芯片丢弃,只留下检测结果为两个好的芯片并随机丢弃一片,并根据芯片数量的奇偶性,将奇数的芯片剩余的一片未匹配的芯片与前面匹配完成并实现丢弃的芯片进行逐一匹配,以此实现缩小芯片数量并确保好芯片至少比坏芯片数量多一片的条件。当芯片数量只剩三片的时候,根据其条件只有两好一坏或者三个好的情况,做简单判断即可找出一片好芯片。//注释的为原先未优化的算法
import java.util.Scanner;
class Chip{//芯片类
boolean quality;//标注好坏
int position;//保存芯片初始化位置
public Chip(boolean quality,int position){
this.quality = quality;
this.position = position;
}
public static void init(Chip chips[],int inits[]){
for(int i=0;i<chips.length;i++){
if(inits[i]==0){
chips[i] = new Chip(false,i);
}else{
chips[i] = new Chip(true,i);
}
}
}
public boolean Chiptest(Chip chip){
if(this.quality) {
return chip.quality;
}
else{
long flag = Math.round(Math.random());
if(flag==0)
return !chip.quality;
else
return chip.quality;
}
}
}
public class 芯片测试 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int GOODorBAD[] = new int[n];
for(int i=0;i<n;i++){//1为好芯片,0为坏芯片
GOODorBAD[i] = in.nextInt();
}
Chip chips[] = new Chip[n];//创建芯片数组
Chip.init(chips, GOODorBAD);//初始化
System.out.print("第 "+find(chips)+" 块是好芯片");
}
public static int find(Chip chips[]){
int n = chips.length;
while(n>3){
int index = 0;
boolean flag = false;
// if(n%2!=0){//如果芯片数量是奇数块
// int good = 0;
// for(int i=0;i<n-1;i++){//选择最后一块的芯片与其余芯片进行测试
// if(chips[i].Chiptest(chips[n-1])){
// good++;
// }
// }
// if(good>n/2){//测试为好芯片
// flag = true;//保存测试结果
// }
// }
for(int i=0;i<n-1;i+=2){//将芯片进行两两互测
if(chips[i].Chiptest(chips[i+1])&&chips[i+1].Chiptest(chips[i])){//只保留测试结果为两个好的
chips[index++] = chips[i];//将其中一片芯片保存下来
}
}
if(n%2!=0&&index%2==0)//奇数块芯片-1块互测完,如果两个好的情况数有偶数种则说明里面好的块数最多等于坏的块数,此时需要保存最后一块芯片
chips[index++] = chips[n-1];
// if(flag) {//取出刚才未匹配的芯片,如果是好芯片,保存下来
// chips[index++] = chips[n-1];
// }
n = index;//一轮测试后芯片数量规模减小,并且确保了好芯片数量至少比坏芯片多一片
}
if(n==3){//边界条件,剩下三块芯片,结果只能是两好一坏或者是三个好的情况之一
if(!(chips[0].Chiptest(chips[1])&&chips[1].Chiptest(chips[0]))){//如果下标0或1的有个坏芯片,则下标2必为好芯片
return chips[2].position+1;//返回好芯片的初始下标。
}
}
if(n==2) {//剩下两块芯片
return chips[1].position+1;
}
//剩下一块芯片
return chips[0].position+1;
}
}