题目如下:
请回答下面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
解决思路:
抛开题目中的逻辑不谈,所有可能性就是 5^10 这么多,但是由于题目中一个一个条件互相约束,这样题目的大难就会减少很多。
一个肯定可以实现的方法就是,借助计算机的快速运算,把每种可能都列出来,然后依次检查是不是符合十道题目的要求,如果都符合,那这便是一个正确的答案了。
用一个数组存放 A, B, C, D, E 四个字母;
写一个函数,按照顺序把可能的答案填在答案数组中;
用生成的这个答案依次执行十道题目的判断,如果全部通过就得到一个可用答案;
重复上面的操作,直到把所有的可能答案都判断过。
运行结果:
最终得到一组答案,经人工验证可行。
总结:
这道题目的逻辑性很强,应该说好好算题目会有简单的方法,利用逻辑关系来排除很多不可能的情况,最终确定。可惜现在还不会这么写程序,只会使用最原始的方法,确实不够灵活。
现在用的 Java 完全是在当 C 语言用,没用使用到面向对象,希望将来可以运用吧。
现在编程在构建程序上还没有形成一个很好的习惯,尤其是在写完一块程序的测试上,有时候很吃力。
此外在编写一些逻辑结构时 return 之类的用的有点随意,还有有的函数不知道用参数好,还是直接用实例变量来的直接。
总之认识到当前的不足,将来看书或者是阅读别人程序时看到自己不足的地方就好好记下来,好好学习吧!
public class CheckAnswer {
static char[] answerOne = {'A', 'B', 'C', 'D', 'E'};
public static void main(String[] args) {
char[] answerAll = new char[10];
// 计算一共有多少种可能的答案组合
int max = (int)Math.pow(5, 10);
// 对每种可能的答案进行检测
for (int i = 0; i < max; i++) {
boolean stillAnAnswer = true;
getAnswerAll(answerAll, i);
// 分别判断每一道题目是否成立
if (!checkAnswer1(answerAll)) {
continue;
}
if (!checkAnswer2(answerAll)) {
continue;
}
if (!checkAnswer3(answerAll)) {
continue;
}
if (!checkAnswer4(answerAll)) {
continue;
}
if (!checkAnswer5(answerAll)) {
continue;
}
if (!checkAnswer6(answerAll)) {
continue;
}
if (!checkAnswer7(answerAll)) {
continue;
}
if (!checkAnswer8(answerAll)) {
continue;
}
if (!checkAnswer9(answerAll)) {
continue;
}
// 可以执行到这里说明答案可行,打印出来
for (int j = 0; j < 10; j++) {
System.out.print((j + 1) + "." + answerAll[j] + " ");
}
System.out.println();
}
}
// 根据编号,得到这组的答案排列
static void getAnswerAll(char[] answerAll, int index) {
for (int i = 0; i < 10; i++) {
answerAll[i] = answerOne[index % 5];
index /= 5;
}
}
static boolean checkAnswer1 (char[] answerAll){
// (1)第一个答案是B的问题是哪一个?
// A.2 B.3 C.4 D.5 E.6
// 得到第一个 B 是多少
int firstB = 0;
for (int i = 0; i < 6; i++) {
if (answerAll[i] == 'B') {
firstB = i;
break;
}
}
// 查看是否与答案相符
if ((answerAll[0] - 'A' + 1) == firstB) {
return true;
}
else {
return false;
}
}
static boolean checkAnswer2 (char[] answerAll){
// (2)唯一的连续两个具有相同答案的问题是:
// A.2,3 B.3,4 C.4,5 D.5,6 E.6,7
boolean haveAnEqual = false;
boolean onlyHavaAnEqual = true;
int equalNum = 0;
for (int i = 0; i < 8; i++) {
if (answerAll[i] == answerAll[i + 1]) {
if (!haveAnEqual) {
haveAnEqual = true;
equalNum = i;
}
else {
onlyHavaAnEqual = false;
break;
}
}
}
if (onlyHavaAnEqual) {
if (equalNum == (answerAll[1] - 'A' + 1)) {
return true;
}
}
return false;
}
static boolean checkAnswer3 (char[] answerAll){
// (3)本问题答案和哪一个问题的答案相同?
// A.1 B.2 C.4 D.7 E.6
switch (answerAll[2]) {
case 'A':
if (answerAll[2] == answerAll[0]) {
return true;
}
break;
case 'B':
if (answerAll[2] == answerAll[1]) {
return true;
}
break;
case 'C':
if (answerAll[2] == answerAll[3]) {
return true;
}
break;
case 'D':
if (answerAll[2] == answerAll[6]) {
return true;
}
break;
case 'E':
if (answerAll[2] == answerAll[5]) {
return true;
}
break;
default:
break;
}
return false;
}
static boolean checkAnswer4 (char[] answerAll){
// (4)答案是A的问题的个数是:
// A.0 B.1 C.2 D.3 E.4
int AAmount = 0;
for (char c : answerAll) {
if (c == 'A') {
AAmount++;
}
}
if ((answerAll[3] - 'A') == AAmount) {
return true;
}
else {
return false;
}
}
static boolean checkAnswer5 (char[] answerAll){
// (5)本问题答案和哪一个问题的答案相同?
// A.10 B.9 C.8 D.7 E.6
switch (answerAll[4]) {
case 'A':
if (answerAll[4] == answerAll[9]) {
return true;
}
break;
case 'B':
if (answerAll[4] == answerAll[8]) {
return true;
}
break;
case 'C':
if (answerAll[4] == answerAll[7]) {
return true;
}
break;
case 'D':
if (answerAll[4] == answerAll[6]) {
return true;
}
break;
case 'E':
if (answerAll[4] == answerAll[5]) {
return true;
}
break;
default:
break;
}
return false;
}
static boolean checkAnswer6 (char[] answerAll){
// (6)答案是A的问题的个数和答案是什么的问题的个数相同?
// A.B B.C C.D D.E E.以上都不是
int[] answerAmount = {0, 0, 0, 0, 0};
for (char c : answerAll) {
answerAmount[c - 'A']++;
}
// 如果答案不是 E
if (answerAll[5] != 'E') {
// 检查答案为 A 的数量与答案约束的选项的数量是否相等
if (answerAmount[0] == answerAmount[answerAll[5] - 'A' + 1]) {
return true;
}
}
// 如果答案是 E 则检查数量却似不同
else {
for (int i = 1; i < 5; i++) {
if (answerAmount[0] == answerAmount[i]) {
return false;
}
}
return true;
}
return false;
}
static boolean checkAnswer7 (char[] answerAll){
// (7)按照字母顺序,本问题的答案和下一个问题的答案相差几个字母?
// A.4 B.3 C.2 D.1 E.0(注:A和B相差一个字母)
if (Math.abs(answerAll[6] - answerAll[7]) == ('E' - answerAll[6])) {
return true;
}
else {
return false;
}
}
static boolean checkAnswer8 (char[] answerAll){
// (8)答案是元音字母的问题的个数是:
// A.2 B.3 C.4 D.5 E.6(注:A和E是元音字母)
int vowelAmout = 0;
for (char c : answerAll) {
if ((c == 'A') || (c == 'E')) {
vowelAmout++;
}
}
if (vowelAmout == (answerAll[7] - 'A' + 2)) {
return true;
}
else {
return false;
}
}
static boolean checkAnswer9 (char[] answerAll){
// (9)答案是辅音字母的问题的个数是:
// A.一个质数 B.一个阶乘数 C.一个平方数 D.一个立方数 E.5的倍数
int consonantAmount = 0;
for (char c : answerAll) {
if ((c != 'A') && (c != 'E')) {
consonantAmount++;
}
}
switch (answerAll[8]) {
// 质数 3 5 7
case 'A':
if ((consonantAmount == 3) || (consonantAmount == 5) || (consonantAmount == 7)) {
return true;
}
break;
// 阶乘数
case 'B':
if (consonantAmount == 6) {
return true;
}
break;
// 平方数 4
case 'C':
if (consonantAmount == 4) {
return true;
}
break;
// 立方数 8
case 'D':
if (consonantAmount == 8) {
return true;
}
break;
// 5 的倍数 5
case 'E':
if (consonantAmount == 5) {
return true;
}
break;
default:
break;
}
return false;
}
}