最近在网上看到了一道所谓的“史上”最难逻辑题

史上最难逻辑题

本来我对这种蛋疼的东西是没有什么兴趣的,但是在逛人人的时候,看到一个同学用编程做出了答案,不过代码写的实在难看,而这几天我正好在复习C语言,所以我也手痒用C++写了一个,并没有什么高深的算法,只不过把那一堆丑陋的循环改成了递归,然后就是用各个题目的条件判断答案是否正确。

在编写代码的时候,我发现,如果真要手算的话,这题也是有突破口,即第八题和第九题,可以很容易的推断出选项A的个数为2或3,而且第十题是个废题,根据其他题,花一点时间,应该不难得出答案。

答案是:A C B C A C D D B A

代码如下:

#include <iostream>
using namespace std;

//判断一个答案序列是否正确
bool prove(char data[]){
    bool question[10];
    for(int i = 0; i < 10; i++)
        question[i] = false;

    int tmp[8]; 
    /*tmp[0]~tmp[3]是ABCD四个选项的个数,
    tmp[4]是和选A个数相同的选项号
    tmp[5]是第七题和第八题选项号差
    tmp[6]是BCD三个选项个数和
    tmp[7]是和下题答案相同的题号*/
    for(int i = 0; i < 8; i++)
        tmp[i] = 0;
    for(int i = 0; i < 10; i++){
        if(data[i] == 'A')
            tmp[0]++;
        else if(data[i] == 'B')
            tmp[1]++;
        else if(data[i] == 'C')
            tmp[2]++;
        else
            tmp[3]++;
    }

    for(int i = 0; i < 10; i++){
        if(data[i] == 'A'){
            if(i == (int)data[0] - 65){
                question[0] = true;
                break;
            }
        }
    }

    int same_as_next = 0;
    for(int i = 0; i < 9; i++){
        if(data[i] == data[i + 1]){
            if(same_as_next == 0){
                same_as_next++;
                tmp[7] = i;
            }else{
                same_as_next++;
                break;
            }
        }
    }

    if(same_as_next == 1 && tmp[7] == (int)data[1] - 61)
        question[1] = true;


    for(int i = 0; i < 10; i++){
        if(data[i] == data[2] && i != 2){
            if((i == 3 && data[i] == 'A') || (i == 8 && data[i] == 'B') || (i == 7 && data[i] == 'C') || (i == 1 && data[i] == 'D')){
                question[2] = true;
                break;
            }
        }
    }

    if(tmp[0] == 70 - (int)data[3])
        question[3] = true;

    for(int i = 0; i < 10; i++){
        if(data[i] == data[4] && i != 4){
            if(i == (int)data[4] - 65){
                question[4] = true;
                break;
            }
        }
    }

    bool same_as_A = false;
    for(int i = 1; i < 4; i++){
        if(tmp[i] == tmp[0]){
            same_as_A = true;
            tmp[4] = i;
        }
    }
    if(same_as_A == false && data[5] == 'A')
        question[5] = true;
    else{
        if(tmp[4] == 2 && (data[5] == 'B' || data[5] == 'C'))
            question[5] = true;
        else if(tmp[4] == 3 && data[5] == 'D')
            question[5] = true;
    }

    tmp[5] = (int)data[6] >= (int)data[7] ? (int)data[6] - (int)data[7] : (int)data[7] - (int)data[6];
    if(tmp[5] == 68 - data[6])
        question[6] = true;

    if(tmp[0] == (int)data[7] - 65)
        question[7] = true;

    tmp[6] = tmp[1] + tmp[2] + tmp[3];
    if((data[8] == 'A' && tmp[6] == 8) || (data[8] == 'B' && tmp[6] == 7))
        question[8] = true;

    question[9] = true;

    for(int i = 1; i < 10; i++)
        question[i] = question[i] && question[i - 1];

    return question[9];
}

//枚举所有答案序列
void enumerate(char data[], int length){
    if(length == 9){
        if(prove(data)){
            for(int i = 0; i < 10; i++)
                cout << data[i] << ' ';
            cout << endl;
        }
    }else{
        length++;
        data[length] = 'A'; // A = 65
        enumerate(data, length);
        data[length] = 'B'; // B = 66
        enumerate(data, length);
        data[length] = 'C'; // C = 67
        enumerate(data, length);
        data[length] = 'D'; // D = 68
        enumerate(data, length);
    }
}

int main(){
    char data[10];
    enumerate(data, -1);
}