前不久在网上看到了一组有趣的问题,具体如下:
1,第一个答案是 A 的问题是哪一个()
A,1 B, 2 C, 3 D, 4
2,唯一的连续两个具有相同答案的问题是()
A,56,B,67 C,78 D,89
3,本题答案和那一题答案相同()
A,4 B,9 C,8 D,2
4,答案是 A 的问题个数是()
A,5 B,4 C,3 D,2
5,本题答案和哪一题答案相同()
A,1 B,2 C,3 D,4
6,答案选 A 的问题的个数和答案选什么的问题个数相同()
A,无 B,C C,C D,D
7,按照字母顺序,本题与下一题相差()(A 与 B 间,或者 B 与 A 间均相差 1)
A,3 B,2 C,1 D,0
8,十道题中答案为元音的题数为()
A,0 B,1 C,2 D,3
9,十道题中答案为辅音的题数()
A,是合数 B 是质数 C,<5 D,是平方数
10, 本题答案为()
A,A B,B C,C D,D
最开始想到的是最原始最简单的穷举法。做个简单的计算,每道题都有四个选择,因此一共是4**10(4的10次方)=1048576种情况,使用手工穷举一百万次可能需要好几年,但是交给计算机也就不到一秒的事。将上述文字转化为C语言的代码如下,环境是:ubuntu12.04,gcc4.7.2
穷举的结果是:唯一的答案: ACBCA CDDBA
其实我觉得这种问题应该能用数学方法得到一种严谨的解,特别期待哪位数学大牛精彩演绎。
/*****************************
***author : yangluo
***date : 3.1.2014
***description : this file is a solution for a group of fascinating questions.
the basic idea is exhaustivity
******************************/
#include<stdio.h>
#include<stdlib.h>
//#include<time.h>
#define A 0
#define B 1
#define C 2
#define D 3
#define WRONG -1
#define CORRECT 1
#define COMPLETE -1
#define Q_COUNT 11 //questions count
int question1(int *answer);
int question2(int *answer);
int question3(int *answer);
int question4(int *answer);
int question5(int *answer);
int question6(int *answer);
int question7(int *answer);
int question8(int *answer);
int question9(int *answer);
int question10(int *answer);
void printResult(int *answer);
int four_system_plus(int *answer,int position);
int main(){
//answer[] is used to store the solution of these questions
//note that 10 questions but the length is 11, for the answer[0] is the
//answer of the questions ,but a flag to sign the end of sulution count.
//more details you can see function "four_system_plus()"
int answer[Q_COUNT]={A,A,A,A,A,A,A,A,A,A,A}; //init answer all 'A'
//correct_count count the num of the right answer in current answer[]
int i, correct_count=0,solution_num=0;
//question_list is a "function array pointer" ,point to 10 questions
int (*question_list[10])(int *) = {question1,question2,question3,\
question4,question5,question6,\
question7,question8,question9,\
question10};
while(1){
//change answer[] by "four_system_plus"
if(COMPLETE == four_system_plus(answer,Q_COUNT-1) ){
//if four_system_plus() returns -1 ,signs exhaustivity complete
printf("solution_num : %d\nend\n",solution_num);
break;
}
correct_count=0;
for(i=0; i<10; i++){
if( question_list[i](answer) == WRONG){
//question_list()returns -1 means this answer[i]is wrong
break;
}else{
//answer[i] fits question[i],so correct_count plus
correct_count++;
}
}
if(correct_count == 10){
//correct_count is 10 means answer[] all fit 10 questions
//so this answer is the solution for this 10 questions
solution_num++; //
printf("correct!!\n");
//print this solution
char ans;
for (i=1; i<Q_COUNT; i++){
switch(answer[i]){
case A : ans = 'A';break;
case B : ans = 'B';break;
case C : ans = 'C';break;
case D : ans = 'D';break;
default: ans = 'E';break;
}
printf("num%-3d: %c\n", i, ans);
}
}
}
return 0;
}
int question1(int *answer){
if (answer[answer[1]] == A){
return CORRECT;
}else{
return WRONG;
}
}
int question2(int *answer){
int i;
int ans = answer[2];
if (ans == A){
if (answer[5] != answer[6]){
return WRONG;
}
}else if (ans == B){
if (answer[6] != answer[7]){
return WRONG;
}
}else if (ans == C){
if (answer[7] != answer[8]){
return WRONG;
}
}else if (ans == D){
if (answer[8] != answer[9]){
return WRONG;
}
}
for (i=1; i<Q_COUNT-1; i++){
if (i == ans+5) continue;
if (answer[i] == answer[i+1]) return WRONG;
}
return CORRECT;
}
int question3(int *answer){
int ans = answer[3];
switch (ans){
case A : if (ans != answer[4]) return WRONG;
return CORRECT;
case B : if (ans != answer[9]) return WRONG;
return CORRECT;
case C : if (ans != answer[8]) return WRONG;
return CORRECT;
case D : if (ans != answer[2]) return WRONG;
return CORRECT;
default: return WRONG;
}
return CORRECT;
}
int question4(int *answer){
int i;
int A_count=0, ans=answer[4];
for(i=1; i<Q_COUNT; i++ ){
if( answer[i] == A) A_count++;
}
switch(ans){
case A : if (A_count == 5) return CORRECT;
break;
case B : if (A_count == 4) return CORRECT;
break;
case C : if (A_count == 3) return CORRECT;
break;
case D : if (A_count == 2) return CORRECT;
break;
default: break;
}
return WRONG;
}
int question5(int *answer){
int ans = answer[5];
switch(ans){
case A : if (answer[1] == ans) return CORRECT;
break;
case B : if (answer[2] == ans) return CORRECT;
break;
case C : if (answer[3] == ans) return CORRECT;
break;
case D : if (answer[4] == ans) return CORRECT;
break;
default: break;
}
return WRONG;
}
int question6(int *answer){
int ans = answer[6];
int choice_count[4]={0,0,0,0};
int i;
for (i=1; i<Q_COUNT; i++){
switch(answer[i]){
case A : choice_count[A]++;break;
case B : choice_count[B]++;break;
case C : choice_count[C]++;break;
case D : choice_count[D]++;break;
default: break;
}
}
switch(ans){
case B : if (choice_count[C] == choice_count[A]) return CORRECT;
break;
case C : if (choice_count[C] == choice_count[A]) return CORRECT;
break;
case D : if (choice_count[D] == choice_count[A]) return CORRECT;
break;
case A : if ((choice_count[A] != choice_count[C]) && \
(choice_count[A] != choice_count[D]) && \
(choice_count[A] != choice_count[B]) ) return CORRECT;
break;
default:break;
}
return WRONG;
}
int question7(int * answer){
int ans=answer[7];
int ans_next=answer[8];
switch (ans){
case A : if (ans_next == D) return CORRECT;
break;
case B : if (ans_next == D) return CORRECT;
break;
case C : if (ans_next == D || ans_next == B) return CORRECT;
break;
case D : if (ans_next == D) return CORRECT;
break;
default: break;
}
return WRONG;
}
int question8(int *answer){
int i;
int A_count=0, ans=answer[8];
for(i=1; i<Q_COUNT; i++ ){
if( answer[i] == A) A_count++;
}
switch(ans){
case A : if (A_count == 0) return CORRECT;
break;
case B : if (A_count == 1) return CORRECT;
break;
case C : if (A_count == 2) return CORRECT;
break;
case D : if (A_count == 3) return CORRECT;
break;
default: break;
}
return WRONG;
}
int question9(int *answer){
int N_A_count=0;
int ans=answer[9];
int i;
for(i=1; i<Q_COUNT; i++){
if(answer[i] != A) N_A_count++;
}
switch(ans){
case A : if (N_A_count==4 || N_A_count==6||\
N_A_count==8 || N_A_count==9||N_A_count==10)
return CORRECT;
break;
case B : if (N_A_count==1 || N_A_count==2||\
N_A_count==3 || N_A_count==5||N_A_count==7)
return CORRECT;
break;
case C : if (N_A_count < 5) return CORRECT;
break;
case D : if (N_A_count==1||N_A_count==4||N_A_count==9)
return CORRECT;
break;
default: break;
}
return WRONG;
}
int question10(int *answer){
return CORRECT;
}
void printResult(int *answer){
int i;
char ans;
for (i=1; i<Q_COUNT; i++){
switch(answer[i]){
case A : ans = 'A';break;
case B : ans = 'B';break;
case C : ans = 'C';break;
case D : ans = 'D';break;
default: ans = 'x';break;
}
printf("num%-3d: %c\n", i, ans);
}
}
/****************************************************************************
four_system_plus is used to change the answer[],for example:
*************
answer[] is "AAAAA" ==> * PLUS * ==> "AAAAB" (note:A+1=B)
^ * * ^ (looks like 00000+1=00001)
*************
*************
answer[] is "ABCD" ==> * PLUS * ==> "ABDA" (note:CD+1=DA)
^^ * * ^^ (looks like 0123+1=0130)
*************
answer[0] is a flag ,it is initialized by A, when it turns to B ,it means that the exhaustivity complete. For example:
when: "ADDDD" ==> "PLUS" ==> "BAAAA" (this looks like "09999"+1="10000")
^ ^
******************************************************************************/
int four_system_plus(int *answer,int position){
//if flag turns B then return -1 ,means exhaustivity complete
if(answer[0] == B){
return COMPLETE;
}
if(answer[position] != D){
answer[position]++;
return CORRECT;
}
position--; //point to the front position
four_system_plus(answer,position); //plus the front position
answer[position+1] = A; //reset the back position to A
return CORRECT;
}