疯狂的谜题 用代码的解析

回答下面 10 道问题,每道题只有一个正确答案。

1、第一个答案是 B 的问题是?

A) 2 B) 3 C)4 D) 5 E)6

2、唯一的连续两个具有相同答案的是?

A) 2,3 B)3,4 C)4,5 D)5,6 E)6,7

3、本问题答案和哪个问题答案相同?

A)1 B)2 C)4 D)7 E)6

4、答案是 A 的问题的个数?

A)0 B)1 C)2 D)3 E)4

5、本问题答案和哪个问题相同?

A)10 B)9 C)8 D)7 E)6

6、答案是 A 的问题的个数和答案是什么的问题的个数相同?

A)B B)C C)D D)E E)以上都不是

7、按照字母顺序本问题的答案和下一个问题的答案相差几个字母?

A)4 B)3 C)2 D)1 E)0 (注:A 和 B 相差一个字母)

8、答案是元音字母的问题的个数?

A)2 B)3 C)4 D)5 E)6 (注: A 和 E 是元音字母)

9、答案是辅音字母的个数?

A)是一个质数 B)是一个阶乘数 C)是一个平方数 D)是一个立方数 E)是 5 的倍数

10、本问题的答案是:

A)A B)B C)C D)D E)E

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

public class Test2 {

// 答案列表,下标0作占位,使下标可以从1开始
private int[] ans = new int[11];

// 数字和答案标号Hash表,下标从1开始对应A
private Map<Integer, String> answerMap = new HashMap<Integer, String>() {
{
put(1, "A");
put(2, "B");
put(3, "C");
put(4, "D");
put(5, "E");
}
};

// 第3题的答案组,下标0为占位
private int[] q3a = {0, 1, 2, 4, 7, 6};

// 第9题的答案组,下标0位占位
private int[] q9a = {0, 7, 6, 4, 8};


/**
* 1、第一个答案是B的问题是?
* A) 2 B) 3 C)4 D) 5 E)6
* <p>
* 可简化为: 当答案是n时,第n+1题的结果等于2为真
*
* @return
*/
private boolean q1() {
int n = ans[1];
return ans[n + 1] == 2;
}

/**
* 2、唯一的连续两个具有相同答案的是?
* A) 2,3 B)3,4 C)4,5 D)5,6 E)6,7
* <p>
* 可简化为: 当答案是n时, 第n+1题和第n+2题结果相同,
* 此外的n-x与n-x+1、n+x与n+x+1的结果都不同。
*
* @return
*/
private boolean q2() {
int n = ans[2];

boolean answer = (ans[n + 1] == ans[n + 2]);
boolean before = false;
boolean after = false;

for (int x = 1; x < n + 1; x++) {
if (ans[x] != ans[x + 1]) {
before = true;
} else {
before = false;
break;
}
}

for (int x = n + 2; x < 10; x++) {
if (ans[x] != ans[x + 1]) {
after = true;
} else {
after = false;
break;
}
}

return before && answer && after;
}

/**
* 3、本问题答案和哪个问题答案相同?
* A)1 B)2 C)4 D)7 E)6
* <p>
* 可简化为: 当答案为n时,第q3a[n]题的答案也为n。
*
* @return
*/
private boolean q3() {
int n = ans[3];
return ans[q3a[n]] == n;
}

/**
* 4、答案是A的问题的个数?
* A)0 B)1 C)2 D)3 E)4
* <p>
* 可简化为: 当答案为n时,答案为A的个数为n-1。
*
* @return
*/
private boolean q4() {
int n = ans[4];
return ansnum(1) == n - 1;
}

/**
* 5、本问题答案和哪个问题相同?
* A)10 B)9 C)8 D)7 E)6
* <p>
* 可简化为: 当答案为n时,第11-n题答案也为n。
*
* @return
*/
private boolean q5() {
int n = ans[5];
return ans[11 - n] == n;
}

/**
* 6、答案是A的问题的个数和答案是什么的问题的个数相同?
* A)B B)C C)D D)E E)以上都不是
* <p>
* 可简化为: 当答案为n时,n小于5时,答案为n+1的问题个数也为n
* 当n=5时,答案为A的问题个数与其它答案的个数均不同。
*
* @return
*/
private boolean q6() {
int n = ans[6];
if (n < 5) {
return ansnum(n + 1) == n;
} else {
return ansnum(1) != ansnum(2) &&
ansnum(1) != ansnum(3) &&
ansnum(1) != ansnum(4) &&
ansnum(1) != ansnum(5);
}
}


/**
* 7、按照字母顺序本问题的答案和下一个问题的答案相差几个字母?
* A)4 B)3 C)2 D)1 E)0 (注:A和B相差一个字母)
* <p>
* 可简化为: 当答案为n时,本题与第8题的答案相减的绝对值为为5-n
*
* @return
*/
private boolean q7() {
int n = ans[7];
return Math.abs(n - ans[8]) == 5 - n;
}

/**
* 8、答案是元音字母的问题的个数?
* A)2 B)3 C)4 D)5 E)6 (注: A和E是元音字母)
* <p>
* 可简化为: 当答案是n时,答案为A、E的问题个数为n+1。
*
* @return
*/
private boolean q8() {
int n = ans[8];
return ansnum(1) + ansnum(5) == n + 1;
}

/**
* 9、答案是辅音字母的个数?
* A)是一个质数 B)是一个阶乘数 C)是一个平方数 D)是一个立方数 E)是5的倍数
* <p>
* 可简化为: 当答案为n时,答案为B、C、D的问题个数为可能为上述内容。
* 其中质数可能为:2、3、5、7
* 阶乘数可能为:1、2、6
* 平方数可能为:1、4、9
* 立方数可能为:1、8
* 5的倍数为:5、10
* 由于同一个问题不可能有多个答案,故应删除重复的数字
* 另本题与第8题答案相关,故本题答案应限制在[4,8]的区间
* 即前选项A-D分别指7、6、4、8, E选项的5或10均不符合要求
*
* @return
*/
private boolean q9() {
int n = ans[9];
if (n == 5) {
return false;
} else {
return ansnum(2) + ansnum(3) + ansnum(4) == q9a[n];
}

}

/**
* 10、本问题的答案是:
* A)A B)B C)C D)D E)E
* <p>
* 本题答案仅在其它答案全部确定时有唯一值,故不需要判断本题。
*
* @return
*/
private boolean q10() {
return true;
}

/**
* 获取答案为n的问题个数
*
* @param n
*
* @return
*/
private int ansnum(int n) {
int count = 0;
for (int a : ans) {
if (a == n) {
count++;
}
}
return count;
}

private void printResult() {
System.out
.println(answerMap.get(ans[1])
+ answerMap.get(ans[2])
+ answerMap.get(ans[3])
+ answerMap.get(ans[4])
+ answerMap.get(ans[5])
+ " "
+ answerMap.get(ans[6])
+ answerMap.get(ans[7])
+ answerMap.get(ans[8])
+ answerMap.get(ans[9])
+ answerMap.get(ans[10]));
}

@Test
public void test1() {
for (ans[1] = 1; ans[1] <= 5; ans[1]++) {
for (ans[2] = 1; ans[2] <= 5; ans[2]++) {
for (ans[3] = 1; ans[3] <= 5; ans[3]++) {
for (ans[4] = 1; ans[4] <= 5; ans[4]++) {
for (ans[5] = 1; ans[5] <= 5; ans[5]++) {
for (ans[6] = 1; ans[6] <= 5; ans[6]++) {
for (ans[7] = 1; ans[7] <= 5; ans[7]++) {
for (ans[8] = 1; ans[8] <= 5; ans[8]++) {
for (ans[9] = 1; ans[9] <= 5; ans[9]++) {
for (ans[10] = 1; ans[10] <= 5; ans[10]++) {
if (q1() && q2() && q3() && q4() && q5() &&
q6() && q7() && q8() && q9() && q10()) {
printResult();
}
}
}
}
}
}
}
}
}
}
}
}
}

运行结果:CDEBE EDCBA

另附上一位大神手算的过程:

  1. 时侯不定;另外两种情况下是确定的 C 或者 D。
  2. 考虑 2:A 不可能,否则 123 矛盾;如果选 B,则 1234 的答案为 ABCC;和 789 的三种情况分别比对,发现都不适合。
  3. 跳到 3:很容易看出,由于 2 的 AB 都不可能,则 3 的 ABC 都不可能;如果为 D,则 7 的答案也为 D,那么 789 的答案确定,再推其他几个答案,都不适合。所以 3 的答案只能为 E。则 6 的答案为 E。
  4. 再回到 1,由于 2、3、6 的答案都不可能是 B,则只可能选 C 或者 D,分别代入,很快可以排除 D,选 C。
  5. 后面的就好推了。