利用回溯算法解复杂题目

有一道这样的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。

 

于是想到了写个程序来解这道题

要遍历所有可能的答案的组合,对每种答案进行验证,看是否满足所有问题。

于是使用递归+回溯的算法来解这道题。

  1. //预定义
  2.         const int QUETIONS_COUNT = 10;      //问题总数
  3.         private char[] answers = new char[] { '-''-''-''-''-''-''-''-''-''-' };//答案集

对每个问题建模,即构造一个函数来验证

  1.         private bool quetion1(char[] answers)
  2.         {
  3.             char currentA = answers[0];     //每个问题的验证中都用currentA来记录当道问题选中的答案
  4.             int first = -1;
  5.             for (int i = 0; i < answers.Length; i++)
  6.             {
  7.                 if (answers[i] == 'b')
  8.                 {
  9.                     first = i + 1;
  10.                     break;
  11.                 }
  12.             }
  13.             //如果答案是a,那么第一个选b的应该是第2道问题;以此类推;答案b永远不成立,因为如果选的是b,那第一道选b的是1
  14.             if ((currentA == 'a' && first == 2)
  15.                 || (currentA == 'c' && first == 4)
  16.                 || (currentA == 'd' && first == 5)
  17.                 || (currentA == 'e' && first == 6))
  18.             {
  19.                 return true;
  20.             }
  21.             return false;
  22.         }
  1.         private bool quetion2(char[] answers)
  2.         {
  3.             char currentA = answers[1];
  4.             int first = -1;     //记录first的原因是因为题目是唯一的,所以要判断除成立的这一对以外是否还有其他对
  5.             switch (currentA)
  6.             {
  7.                 case 'a':
  8.                     if (answers[1] != answers[2])
  9.                         return false;
  10.                     else
  11.                         first = 1;
  12.                     break;
  13.                 case 'b':
  14.                     if (answers[2] != answers[3])
  15.                         return false;
  16.                     else
  17.                         first = 2;
  18.                     break;
  19.                 case 'c':
  20.                     if (answers[3] != answers[4])
  21.                         return false;
  22.                     else
  23.                         first = 3;
  24.                     break;
  25.                 case 'd':
  26.                     if (answers[4] != answers[5])
  27.                         return false;
  28.                     else
  29.                         first = 4;
  30.                     break;
  31.                 case 'e':
  32.                     if (answers[5] != answers[6])
  33.                         return false;
  34.                     else
  35.                         first = 5;
  36.                     break;
  37.             }
  38.             for (int i = 0; i < answers.Length; i++)    //判断是否还有其他对连续一样的答案,有则返回false
  39.             {
  40.                 if (i == first) continue;
  41.                 if (i + 1 < answers.Length && answers[i] == answers[i + 1])
  42.                 {
  43.                     return false;
  44.                 }
  45.             }
  46.             return true;
  47.         }

 

  1.         private bool quetion3(char[] answers)
  2.         {
  3.             char currentA = answers[2];
  4.             //比较简单的判断,如果该道选a,那第一道也应该要选a,否则就返回false,以此类推
  5.             if ((currentA == 'a' && answers[0] == 'a')
  6.                 || (currentA == 'b' && answers[1] == 'b')
  7.                 || (currentA == 'c' && answers[3] == 'c')
  8.                 || (currentA == 'd' && answers[6] == 'd')
  9.                 || (currentA == 'e' && answers[5] == 'e'))
  10.             {
  11.                 return true;
  12.             }
  13.             return false;
  14.         }

 

  1.         private bool quetion4(char[] answers)
  2.         {
  3.             char currentA = answers[3];
  4.             int aA = 0;     //记录选a的个数
  5.             //统计选a的个数
  6.             for (int i = 0; i < answers.Length; i++)
  7.             {
  8.                 if (answers[i] == 'a') aA++;
  9.             }
  10.             //根据当前选项,判断与选a的个数是否相符
  11.             if ((currentA == 'a' && aA == 0)
  12.                 || (currentA == 'b' && aA == 1)
  13.                 || (currentA == 'c' && aA == 2)
  14.                 || (currentA == 'd' && aA == 3)
  15.                 || (currentA == 'e' && aA == 4))
  16.             {
  17.                 return true;
  18.             }
  19.             return false;
  20.         }

 

  1.         private bool quetion5(char[] answers)
  2.         {
  3.             //和第3道一样
  4.             char currentA = answers[4];
  5.             if ((currentA == 'a' && answers[9] == 'a')
  6.                 || (currentA == 'b' && answers[8] == 'b')
  7.                 || (currentA == 'c' && answers[7] == 'c')
  8.                 || (currentA == 'd' && answers[6] == 'd')
  9.                 || (currentA == 'e' && answers[5] == 'e'))
  10.             {
  11.                 return true;
  12.             }
  13.             return false;
  14.         }

 

  1.         private bool quetion6(char[] answers)
  2.         {
  3.             char currentA = answers[5];
  4.             int aA = 0;
  5.             int aB = 0;
  6.             int aC = 0;
  7.             int aD = 0;
  8.             int aE = 0;
  9.             //统计选a,b,c,d,e的答案各有多少个
  10.             for (int i = 0; i < answers.Length; i++)
  11.             {
  12.                 if (answers[i] == 'a') aA++;
  13.                 if (answers[i] == 'b') aB++;
  14.                 if (answers[i] == 'c') aC++;
  15.                 if (answers[i] == 'd') aD++;
  16.                 if (answers[i] == 'e') aE++;
  17.             }
  18.             switch (currentA)
  19.             {
  20.                 case 'a':   //如果选a,那选a的答案个数应该和选b的答案个数一样,以此类推
  21.                     if (aA == aB)
  22.                         return true;
  23.                     else
  24.                         return false;
  25.                 case 'b':
  26.                     if (aA == aC)
  27.                         return true;
  28.                     else
  29.                         return false;
  30.                 case 'c':
  31.                     if (aA == aD)
  32.                         return true;
  33.                     else
  34.                         return false;
  35.                 case 'd':
  36.                     if (aA == aE)
  37.                         return true;
  38.                     else
  39.                         return false;
  40.                 case 'e':
  41.                     if (aA != aB && aA != aC && aA != aD && aA != aE)
  42.                         return true;
  43.                     else
  44.                         return false;
  45.             }
  46.             return false;
  47.         }

 

  1.         private bool quetion7(char[] answers)
  2.         {
  3.             char currentA = answers[6];
  4.             int i = Math.Abs(currentA - answers[7]);    //计算当前选的答案和第8道选的答案相差多少
  5.             //如果当前选的是a,那第8道的答案应该跟这道答案相差4,以此类推
  6.             if ((currentA == 'a' && i == 4)
  7.                 || (currentA == 'b' && i == 3)
  8.                 || (currentA == 'c' && i == 2)
  9.                 || (currentA == 'd' && i == 1)
  10.                 || (currentA == 'e' && i == 0))
  11.             {
  12.                 return true;
  13.             }
  14.             return false;
  15.         }
    1.         private bool quetion8(char[] answers)
    2.         {
    3.             char currentA = answers[7];
    4.             int bCount = 0;
    5.             //统计元音答案的个数。
    6.             for (int i = 0; i < answers.Length; i++)
    7.             {
    8.                 if (answers[i] == 'a' || answers[i] == 'e')
    9.                 {
    10.                     bCount++;
    11.                 }
    12.             }
    13.             //如果选a,那元音答案应该是2,以此类推
    14.             if ((currentA == 'a' && bCount == 2)
    15.                 || (currentA == 'b' && bCount == 3)
    16.                 || (currentA == 'c' && bCount == 4)
    17.                 || (currentA == 'd' && bCount == 5)
    18.                 || (currentA == 'e' && bCount == 6))
    19.             {
    20.                 return true;
    21.             }
    22.             return false;
    23.         }
  1.         private bool quetion9(char[] answers)
  2.         {
  3.             char currentA = answers[8];
  4.             int bCount = 0;
  5.             //统计辅音答案的个数。
  6.             for (int i = 0; i < answers.Length; i++)
  7.             {
  8.                 if (answers[i] == 'b' || answers[i] == 'c' || answers[i] == 'd')
  9.                 {
  10.                     bCount++;
  11.                 }
  12.             }
  13.             //如果选a,那辅音答案个数应该是2,3,5或7
  14.             //如果选b,那辅音答案个数应该是3,6或10
  15.             //备注:将0,1加入判断范围,对答案并无影响
  16.             //以此类推
  17.             if ((currentA == 'a' && (bCount == 2 || bCount == 3 || bCount == 5 || bCount == 7))
  18.                 || (currentA == 'b' && (bCount == 3 || bCount == 6 || bCount == 10))
  19.                 || (currentA == 'c' && (bCount == 4 || bCount == 9))
  20.                 || (currentA == 'd' && (bCount == 8))
  21.                 || (currentA == 'e' && (bCount == 5 || bCount == 10)))
  22.             {
  23.                 return true;
  24.             }
  25.             return false;
  26.         }

 

以下是核心算法:

  1.         private void Trial(int n)
  2.         {
  3.             for (char a = 'a'; a < 'f'; a++)
  4.             {
  5.                 answers[n] = a;
  6.                 if (!(quetion1(answers) && quetion2(answers) && quetion3(answers)
  7.                     && quetion4(answers) && quetion5(answers) && quetion6(answers)
  8.                     && quetion7(answers) && quetion8(answers) && quetion9(answers)))
  9.                 {
  10.                     if (n < QUETIONS_COUNT - 1)
  11.                     {
  12.                         Trial(n + 1);
  13.                     }
  14.                 }
  15.                 else
  16.                 {
  17.                     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]);
  18.                     break;
  19.                 }
  20.             }
  21.         }

程序入口:

  1.         private void button1_Click(object sender, EventArgs e)
  2.         {
  3.             Trial(0);
  4.         }

算出来的答案是:cdebeedcba

算对了么?呵呵~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值