原题
有n(2≤n≤20)块芯片,有好有坏,已知好芯片比坏芯片多。
每个芯片都能用来测试其他芯片。用好芯片测试其他芯片时,能正确给出被测试芯片是好还是坏。而用坏芯片测试其他芯片时,会随机给出好或是坏的测试结果(即此结果与被测试芯片实际的好坏无关)。
给出所有芯片的测试结果,问哪些芯片是好芯片。
输入格式
输入数据第一行为一个整数n,表示芯片个数。
第二行到第n+1行为n*n的一张表,每行n个数据。表中的每个数据为0或1,在这n行中的第i行第j列(1≤i, j≤n)的数据表示用第i块芯片测试第j块芯片时得到的测试结果,1表示好,0表示坏,i=j时一律为1(并不表示该芯片对本身的测试结果。芯片不能对本身进行测试)。
分析
根据题目所述,好的芯片测试好的芯片结果是正确的,坏的芯片测试会得到一个随机结果。第一看看上去感觉没啥头绪。但是仔细一看,题目的关键信息是 已知好芯片比坏芯片多 这个结合以上信息,可以得出 正确的结果一定是多与错误的结果,也就是说一个芯片被剩余所有的芯片测试所得到的正确的结果一定是多于错误的结果,如果这个芯片是好的那么结果是1的个数一定大于结果是0的个数,反之亦然。 就是只要统计每一列中1的个数和0的个数,将结果进行比较就可以确定芯片的好坏。
这个时候需要考虑的是,判断一个芯片是好芯片条件是1个数大于0个数还是1个数大于等于0个数。这个时候需要考虑一个可能:由于需要去除自己测试自己的结果,如果好芯片个数恰好比坏芯片个数多一个,此时如果坏芯片恰好测试一个好芯片结果全是0,由于结果需要去除自己测试自己,那么此时结果是1和是0的个数相等了,因此如果1和0个数相等也可以判断这个芯片是好芯片。因此可以得出结论:只要一个芯片测试结果中1的个数大于等于0的个数,这个芯片就是好芯片 为了证明这个结论可以举出一个反例:还是上面的情况,如果被测试的恰好是坏芯片,极端情况是:所有坏芯片测试该芯片结果全是1,好芯片测试结果显然是0,排除自己测试自己的结果。如果总共有10个芯片此时,结果是1和0的比利是6:3。显然使用这个条件是可以得到正确结果的
代码实现
#include<iostream>
using namespace std;
int main(){
bool flag[21][21]={0}; //存储测试结果
int n; //芯片个数
cin>>n;
for(int i=0;i<n;i++){ //输入测试结果
for(int j=0;j<n;j++){
cin>>flag[i][j];
}
}
bool x[21]={0}; //判断芯片好坏的结果
int good,bad; //一个芯片测试结果是结果是1和0的个数
for(int i=0;i<n;i++){ //遍历每一个列
good=bad=0; //初始化结果
for(int j=0;j<n;j++){ //遍历指定列的每一行
if(i!=j){ //去除自己测试自己的情况
if(flag[j][i]) //如果该行测试结果是该芯片是好芯片
good++;
else //该行测试结果是该芯片是坏芯片
bad++;
}
}
if(good>=bad){ //测试结果中评价是好芯片个数大于等于是坏芯片个数,则该芯片是好芯片,否则该芯片是坏芯片
x[i]=true;
}
else{
x[i]=false;
}
}
for(int i=0;i<n;i++){ //输出判断结果是是好芯片的芯片编号
if(x[i])
cout<<i+1<<' ';
}
}