#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
//显示所有球
inline void show(const int ball[], int len){
for(int i = 0; i < len; ++i){
cout << ball[i] << " ";
}
cout << endl;
}
//初始化13个球
inline void init(int ball[], int len){
for(int i = 0; i < len; ++i){
ball[i] = 2;
}
}
//插入坏球, 有可能是轻球, 也有可能是重球, 插入到球数组中的任意位置
inline void pushBadBall(int ball[], int len){
int badBalls[] = {1,3};
srand(time(0));
int _badBall = badBalls[rand()%2]; //产生环球
cout << "bad ball: " << _badBall << endl;
ball[rand()%len] = _badBall; //插入坏球
show(ball, len);
}
//数组的合计
int sum(int arr[], int begin, int end){
int sum = 0;
for(int i=(begin-1); i < end; i++){
sum += arr[i];
}
return sum;
}
void getBadBall(int ball[], int len){
//分组, A组4个, B组4个, C组5个
int A[4] = {ball[0],ball[1],ball[2],ball[3]};
int B[4] = {ball[4],ball[5],ball[6],ball[7]};
int C[5] = {ball[8],ball[9],ball[10],ball[11],ball[12]};
bool firstCheck = false; //第一层比较, false 小于, true 大于
bool secondeCheck = false; //第二层比较, 同上
bool thirdCheck = false; //第三层比较, 同上
bool ballFlag = false; //false 轻, true 重
int badBallIndex = len; //坏球的索引
if(sum(A,1,4) == sum(B,1,4)){ //X 表示坏球, 下同, X 在 C 中
if(sum(A,1,3) == sum(C,1,3)){ //X 在 C(4,5) 中
if(A[0] != C[3]){
badBallIndex = 11;
if(A[0] > C[3])
ballFlag = false;
else
ballFlag = true;
}else{
badBallIndex = 12;
if(A[0] < C[4])
ballFlag = false;
else
ballFlag = true;
}
}
else{ //X 在 C(1,2,3) 中
if(sum(A,1,3) > sum(C,1,3)) //X 是轻的
ballFlag = false;
else //X 是重的
ballFlag = true;
if(C[0] == C[1]){
badBallIndex = 10;
}else if(C[0] > C[1]){
if(ballFlag){
badBallIndex = 8;
}else{
badBallIndex = 9;
}
}else{
if(ballFlag){
badBallIndex = 9;
}else{
badBallIndex = 8;
}
}
}
}else{ //X 在 A 或 B 中
if(sum(A,1,4) > sum(B,1,4))
firstCheck = true;
else
firstCheck = false;
if(sum(A,1,3) + sum(B,1,2) == sum(C,1,5)){//X 在 A(4) 或 B(3,4) 中
if(sum(A,4,4) + sum(B,4,4) == sum(C,1,2)){// X 是 B(3)
badBallIndex = 6;
if(firstCheck) //如果第一次比较是大于, X 为轻, 否则为 重
ballFlag = false;
else
ballFlag = true;
}else{
if(sum(A,4,4) + sum(B,4,4) > sum(C,1,2))//
thirdCheck = true;
else thirdCheck = false;
if(firstCheck){
if(thirdCheck){ //第一次大, 第三次大, 证明 X 为A(4) 重
badBallIndex = 3;
ballFlag = true;
}
else { //第一次大, 第三次小, 证明 X 为 B(4) 轻
badBallIndex = 7;
ballFlag = false;
}
}else{
if(!thirdCheck){ //第一次小, 第三次小, 证明 X 为A(4) 轻
badBallIndex = 3;
ballFlag = false;
}
else{ //第一次小, 第三次大, 证明 X 为 B(4) 重
badBallIndex = 7;
ballFlag = true;
}
}
}
}else{ // X 在A(1,3) 或 B(1,2) 中
if(sum(A,1,3) + sum(B,1,2) > sum(C,1,5)){
secondeCheck = true;
ballFlag = true;
}else{
secondeCheck = false;
ballFlag = false;
}
if((firstCheck && ballFlag) || //X重A大, X在A(1-3)中
(!firstCheck && !ballFlag) ){//X轻A小, X在A(1-3)中
if(A[0] == A[1]){
badBallIndex = 2;
}else if(A[0] > A[1]){
if(ballFlag){
badBallIndex = 0;
}else{
badBallIndex = 1;
}
}else{
if(ballFlag){
badBallIndex = 1;
}else{
badBallIndex = 0;
}
}
}else{ //X重B大, X 在 B(1,2) 中
if(B[0] == C[0]){
badBallIndex = 5;
}else{
badBallIndex = 4;
}
}
}
}
cout << "bad ball:" << (ballFlag?3:1) << endl;
cout << "bad ball index(0-12): " << badBallIndex << endl;
}
int main(){
const int NUM =13;
int ball[NUM] = {1};
//初始化
init(ball, NUM);
//插入坏球
pushBadBall(ball, NUM);
//获取坏球
getBadBall(ball, NUM);
system("pause");
return 1;
}
有13个球, 其中一个是坏球 X, 它可能比较轻或比较重, 我们如何称 3 次找出这个坏球 X 呢?
把13个球分成 3 组, A,B,C, A有4个球, B有4个球, C有5个球
A: 1 2 3 4
B: 1 2 3 4
C: 1 2 3 4 5
第一轮先比较 A 和 B
如果A == B, 那第二轮比较 A(1-3) 和 C(1-3)
如果A != B, 那第二轮比较 A(1-3) + B(1-2) 和 C(1-5)
第二轮比较完以后, 出现下面三种情况其中之一, 可以得出结果
1. X 存在于某个组中的3个球中, 并且知道 X 是轻是重.
2. X 存在于某个组中的2个球中, 无需知道 X 轻重.
3. X 存在于两个不同的组, 总共3个球中, 需要通过第一次的比较和第三次的比较 (第三次得出球的轻重, 再结合第一次).
结果:
bad ball: 3
2 2 2 2 2 2 3 2 2 2 2 2 2
bad ball:3
bad ball index(0-12): 6
请按任意键继续. . .
bad ball: 3
2 2 2 2 2 2 2 2 2 2 2 3 2
bad ball:3
bad ball index(0-12): 11
请按任意键继续. . .