有一道这样的BT题
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。
于是想到了写个程序来解这道题
要遍历所有可能的答案的组合,对每种答案进行验证,看是否满足所有问题。
于是使用递归+回溯的算法来解这道题。
- //预定义
- const int QUETIONS_COUNT = 10; //问题总数
- private char[] answers = new char[] { '-', '-', '-', '-', '-', '-', '-', '-', '-', '-' };//答案集
对每个问题建模,即构造一个函数来验证
- private bool quetion1(char[] answers)
- {
- char currentA = answers[0]; //每个问题的验证中都用currentA来记录当道问题选中的答案
- int first = -1;
- for (int i = 0; i < answers.Length; i++)
- {
- if (answers[i] == 'b')
- {
- first = i + 1;
- break;
- }
- }
- //如果答案是a,那么第一个选b的应该是第2道问题;以此类推;答案b永远不成立,因为如果选的是b,那第一道选b的是1
- if ((currentA == 'a' && first == 2)
- || (currentA == 'c' && first == 4)
- || (currentA == 'd' && first == 5)
- || (currentA == 'e' && first == 6))
- {
- return true;
- }
- return false;
- }
- private bool quetion2(char[] answers)
- {
- char currentA = answers[1];
- int first = -1; //记录first的原因是因为题目是唯一的,所以要判断除成立的这一对以外是否还有其他对
- switch (currentA)
- {
- case 'a':
- if (answers[1] != answers[2])
- return false;
- else
- first = 1;
- break;
- case 'b':
- if (answers[2] != answers[3])
- return false;
- else
- first = 2;
- break;
- case 'c':
- if (answers[3] != answers[4])
- return false;
- else
- first = 3;
- break;
- case 'd':
- if (answers[4] != answers[5])
- return false;
- else
- first = 4;
- break;
- case 'e':
- if (answers[5] != answers[6])
- return false;
- else
- first = 5;
- break;
- }
- for (int i = 0; i < answers.Length; i++) //判断是否还有其他对连续一样的答案,有则返回false
- {
- if (i == first) continue;
- if (i + 1 < answers.Length && answers[i] == answers[i + 1])
- {
- return false;
- }
- }
- return true;
- }
- private bool quetion3(char[] answers)
- {
- char currentA = answers[2];
- //比较简单的判断,如果该道选a,那第一道也应该要选a,否则就返回false,以此类推
- if ((currentA == 'a' && answers[0] == 'a')
- || (currentA == 'b' && answers[1] == 'b')
- || (currentA == 'c' && answers[3] == 'c')
- || (currentA == 'd' && answers[6] == 'd')
- || (currentA == 'e' && answers[5] == 'e'))
- {
- return true;
- }
- return false;
- }
- private bool quetion4(char[] answers)
- {
- char currentA = answers[3];
- int aA = 0; //记录选a的个数
- //统计选a的个数
- for (int i = 0; i < answers.Length; i++)
- {
- if (answers[i] == 'a') aA++;
- }
- //根据当前选项,判断与选a的个数是否相符
- if ((currentA == 'a' && aA == 0)
- || (currentA == 'b' && aA == 1)
- || (currentA == 'c' && aA == 2)
- || (currentA == 'd' && aA == 3)
- || (currentA == 'e' && aA == 4))
- {
- return true;
- }
- return false;
- }
- private bool quetion5(char[] answers)
- {
- //和第3道一样
- char currentA = answers[4];
- if ((currentA == 'a' && answers[9] == 'a')
- || (currentA == 'b' && answers[8] == 'b')
- || (currentA == 'c' && answers[7] == 'c')
- || (currentA == 'd' && answers[6] == 'd')
- || (currentA == 'e' && answers[5] == 'e'))
- {
- return true;
- }
- return false;
- }
- private bool quetion6(char[] answers)
- {
- char currentA = answers[5];
- int aA = 0;
- int aB = 0;
- int aC = 0;
- int aD = 0;
- int aE = 0;
- //统计选a,b,c,d,e的答案各有多少个
- for (int i = 0; i < answers.Length; i++)
- {
- if (answers[i] == 'a') aA++;
- if (answers[i] == 'b') aB++;
- if (answers[i] == 'c') aC++;
- if (answers[i] == 'd') aD++;
- if (answers[i] == 'e') aE++;
- }
- switch (currentA)
- {
- case 'a': //如果选a,那选a的答案个数应该和选b的答案个数一样,以此类推
- if (aA == aB)
- return true;
- else
- return false;
- case 'b':
- if (aA == aC)
- return true;
- else
- return false;
- case 'c':
- if (aA == aD)
- return true;
- else
- return false;
- case 'd':
- if (aA == aE)
- return true;
- else
- return false;
- case 'e':
- if (aA != aB && aA != aC && aA != aD && aA != aE)
- return true;
- else
- return false;
- }
- return false;
- }
- private bool quetion7(char[] answers)
- {
- char currentA = answers[6];
- int i = Math.Abs(currentA - answers[7]); //计算当前选的答案和第8道选的答案相差多少
- //如果当前选的是a,那第8道的答案应该跟这道答案相差4,以此类推
- if ((currentA == 'a' && i == 4)
- || (currentA == 'b' && i == 3)
- || (currentA == 'c' && i == 2)
- || (currentA == 'd' && i == 1)
- || (currentA == 'e' && i == 0))
- {
- return true;
- }
- return false;
- }
- private bool quetion8(char[] answers)
- {
- char currentA = answers[7];
- int bCount = 0;
- //统计元音答案的个数。
- for (int i = 0; i < answers.Length; i++)
- {
- if (answers[i] == 'a' || answers[i] == 'e')
- {
- bCount++;
- }
- }
- //如果选a,那元音答案应该是2,以此类推
- if ((currentA == 'a' && bCount == 2)
- || (currentA == 'b' && bCount == 3)
- || (currentA == 'c' && bCount == 4)
- || (currentA == 'd' && bCount == 5)
- || (currentA == 'e' && bCount == 6))
- {
- return true;
- }
- return false;
- }
- private bool quetion9(char[] answers)
- {
- char currentA = answers[8];
- int bCount = 0;
- //统计辅音答案的个数。
- for (int i = 0; i < answers.Length; i++)
- {
- if (answers[i] == 'b' || answers[i] == 'c' || answers[i] == 'd')
- {
- bCount++;
- }
- }
- //如果选a,那辅音答案个数应该是2,3,5或7
- //如果选b,那辅音答案个数应该是3,6或10
- //备注:将0,1加入判断范围,对答案并无影响
- //以此类推
- if ((currentA == 'a' && (bCount == 2 || bCount == 3 || bCount == 5 || bCount == 7))
- || (currentA == 'b' && (bCount == 3 || bCount == 6 || bCount == 10))
- || (currentA == 'c' && (bCount == 4 || bCount == 9))
- || (currentA == 'd' && (bCount == 8))
- || (currentA == 'e' && (bCount == 5 || bCount == 10)))
- {
- return true;
- }
- return false;
- }
以下是核心算法:
- private void Trial(int n)
- {
- for (char a = 'a'; a < 'f'; a++)
- {
- answers[n] = a;
- if (!(quetion1(answers) && quetion2(answers) && quetion3(answers)
- && quetion4(answers) && quetion5(answers) && quetion6(answers)
- && quetion7(answers) && quetion8(answers) && quetion9(answers)))
- {
- if (n < QUETIONS_COUNT - 1)
- {
- Trial(n + 1);
- }
- }
- else
- {
- txtA.Text += string.Format("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9} ", answers[0], answers[1], answers[2], answers[3], answers[4], answers[5], answers[6], answers[7], answers[8], answers[9]);
- break;
- }
- }
- }
程序入口:
- private void button1_Click(object sender, EventArgs e)
- {
- Trial(0);
- }
算出来的答案是:cdebeedcba
算对了么?呵呵~