练习55

 
  1. /***********************************************************************************
  2.   55. (液晶显示) 下图是用液晶七笔阿拉数字表示的十个数字,我们把横和竖的一
  3.  个短划都称为一笔,即7有3笔,8有7笔等。请把这十个数字重新排列,要做到
  4.  两相邻数字都可以由另一个数字加上几笔或减去几笔组成,但不能又加又减。比如
  5.  7→3是允许的,7→2不允许。编程打印出所有可能的排列。
  6.     如:4107395682。
  7.   *********************************************************************************/
  8. #include <stdio.h>
  9. //各数字允许排列的下一数字
  10. int Allow0[] = {1,7,8,-1};
  11. int Allow1[] = {0,3,4,7,8,9,-1};
  12. int Allow2[] = {8,-1};
  13. int Allow3[] = {1,7,8,9,-1};
  14. int Allow4[] = {1,8,9,-1};
  15. int Allow5[] = {6,8,9,-1};
  16. int Allow6[] = {5,8,-1};
  17. int Allow7[] = {0,1,3,8,9,-1};
  18. int Allow8[] = {0,1,2,3,4,5,6,7,9,-1};
  19. int Allow9[] = {1,3,4,5,7,8,-1};
  20. //数组地址保存在一个数组,方便访问
  21. int *Allow[10] = {
  22.     Allow0,Allow1,Allow2,Allow3,Allow4,
  23.     Allow5,Allow6,Allow7,Allow8,Allow9
  24. };
  25. int NumberUse[10];//保存数字的使用情况,0-未使用,1-使用
  26. int PL[10];//保存排列
  27. int BL[10];//保存当前分支
  28. //输出排列
  29. void PrintPL()
  30. {
  31.     int i;
  32.     //因为对称性,输出时只需顺序和倒序输出一次即可
  33.     //顺序
  34.     for(i=0; i<10; i++)
  35.         printf("%2d",PL[i]);
  36.     printf("/n");
  37.     //倒序
  38.     for(i=i-1;i>=0; i--)
  39.         printf("%2d",PL[i]);
  40.     printf("/n");
  41. }
  42. //main
  43. void main()
  44. {
  45.     int i,k;
  46.     for(i=0; i<10; i++)
  47.     {
  48.         BL[i] = -1;
  49.     }
  50.     //因为与2相邻的只有8,所以2必须只能排在最前面和最后面
  51.     //两种情况形成对称排列
  52.     PL[0] = 2;
  53.     PL[1] = 8;
  54.     NumberUse[2] = 1;
  55.     NumberUse[8] = 1;
  56.     //回溯搜索
  57.     k=2;
  58.     while(k>=2)
  59.     {
  60.         while((i=Allow[PL[k-1]][++BL[PL[k-1]]])!=-1)
  61.         {
  62.             if(NumberUse[i]==0)
  63.             {
  64.                 PL[k] = i;
  65.                 if(k==9)//成功,搜索下一个
  66.                 {
  67.                     PrintPL();
  68.                     break;
  69.                 }
  70.                 else if(k<9)//合法部分解
  71.                 {
  72.                     NumberUse[i] = 1;
  73.                     k++;
  74.                 }
  75.             }
  76.         }
  77.         //回溯
  78.         BL[PL[k-1]] = -1;
  79.         NumberUse[PL[k-1]] = 0;
  80.         k--;
  81.     }
  82. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值