- /***********************************************************************************
- 55. (液晶显示) 下图是用液晶七笔阿拉数字表示的十个数字,我们把横和竖的一
- 个短划都称为一笔,即7有3笔,8有7笔等。请把这十个数字重新排列,要做到
- 两相邻数字都可以由另一个数字加上几笔或减去几笔组成,但不能又加又减。比如
- 7→3是允许的,7→2不允许。编程打印出所有可能的排列。
- 如:4107395682。
- *********************************************************************************/
- #include <stdio.h>
- //各数字允许排列的下一数字
- int Allow0[] = {1,7,8,-1};
- int Allow1[] = {0,3,4,7,8,9,-1};
- int Allow2[] = {8,-1};
- int Allow3[] = {1,7,8,9,-1};
- int Allow4[] = {1,8,9,-1};
- int Allow5[] = {6,8,9,-1};
- int Allow6[] = {5,8,-1};
- int Allow7[] = {0,1,3,8,9,-1};
- int Allow8[] = {0,1,2,3,4,5,6,7,9,-1};
- int Allow9[] = {1,3,4,5,7,8,-1};
- //数组地址保存在一个数组,方便访问
- int *Allow[10] = {
- Allow0,Allow1,Allow2,Allow3,Allow4,
- Allow5,Allow6,Allow7,Allow8,Allow9
- };
- int NumberUse[10];//保存数字的使用情况,0-未使用,1-使用
- int PL[10];//保存排列
- int BL[10];//保存当前分支
- //输出排列
- void PrintPL()
- {
- int i;
- //因为对称性,输出时只需顺序和倒序输出一次即可
- //顺序
- for(i=0; i<10; i++)
- printf("%2d",PL[i]);
- printf("/n");
- //倒序
- for(i=i-1;i>=0; i--)
- printf("%2d",PL[i]);
- printf("/n");
- }
- //main
- void main()
- {
- int i,k;
- for(i=0; i<10; i++)
- {
- BL[i] = -1;
- }
- //因为与2相邻的只有8,所以2必须只能排在最前面和最后面
- //两种情况形成对称排列
- PL[0] = 2;
- PL[1] = 8;
- NumberUse[2] = 1;
- NumberUse[8] = 1;
- //回溯搜索
- k=2;
- while(k>=2)
- {
- while((i=Allow[PL[k-1]][++BL[PL[k-1]]])!=-1)
- {
- if(NumberUse[i]==0)
- {
- PL[k] = i;
- if(k==9)//成功,搜索下一个
- {
- PrintPL();
- break;
- }
- else if(k<9)//合法部分解
- {
- NumberUse[i] = 1;
- k++;
- }
- }
- }
- //回溯
- BL[PL[k-1]] = -1;
- NumberUse[PL[k-1]] = 0;
- k--;
- }
- }
练习55
最新推荐文章于 2022-11-10 22:36:55 发布