• 网络学院
  • IT资讯
  • 操作系统
  • 网络技术
  • 软件应用
  • 办公软件
  • 编程技术
  • 网站架设
  • 数据库类
  • 平面设计
  • 多媒体类
  • 游戏资讯
  • 教学论文
  • 认证考试
计算机二级:C程序设计例解(07)
  站点:
  • 首 页
  • 最新软件
  • 文章教程
  • 国内软件
  • 国外软件
  • 绿色软件
  • 源码下载
  • 字体下载
计算机二级:C程序设计例解(07)
软件发布 计算机二级:C程序设计例解(07)
网络软件 系统工具 应用软件 联络聊天 图形图像 多媒体类 行业软件 游戏娱乐 编程开发 安全相关 教育教学 数码软件 绿软下载
热门软件: QQ 瑞星 pplive e话通 木马克星 千千静听 office2000 五笔字根 Photoshop 视频分割
返回文章教程首页 >> 认证考试 >> 计算机等级考试 >> 计算机二级考试 >> 计算机二级:C程序设计例解(07)

计算机二级:C程序设计例解(07)

添加时间: 2007-5-5 5:58:19  作者: 计算机等级考试认证参考  阅读次数:22   来源: http://www.d9soft.com

       

07. 有2*n个盒子排成一行,其中有两个相邻的空盒,有n-1个盒子有符号'A',有n-1个盒子有符号'B'。例如,n=5,并有初始配置如下:
A B B A . . A B A B

试编制程序,将输入的盒子排列状态按以下交换规则将全部‘A’放到全部‘B’的左边,不管相邻两空盒的位置。交换规则是任意两个非空相邻盒子的内容可移入两个空盒中,但移动时不得变更两符号的前后次序。编写程序输入初始配置后,找出达到目标要求的最少交换次数的方案。
解:
    从一种盒子排列出发,将其中两个非空相邻盒子中的内容移入空盒的每一种移动,会使盒子产生新的排列状态,采用试探法穷举所有可能的移动找问题的解。首先将盒子初始排列存入移动步聚表,然后是试探和回溯循环。循环工作内容有: 检查 当前排列,若当前排列是要求的最终状态,则将达到该状态的移动步聚保存,并回溯去找更少移动步数的解。在试探超 过限定的深度或当前状态的所有可能移动都已试探穷尽情况下回溯;否则对当前状态取其当前移动方法产生新的后继状态存入移动步聚表,并继续向前试探。为能从某种排列出发,通过移动产生更接近目标要求的排列,对移动方法的选取作如下规定:
    。掠过无意义的来回移动;
    。不把两个相邻的同为符号‘A’的盒子向后移;
    。不把两个相邻的同为符号‘B’的盒子向前移;
    。不把两个盒子移入到这样的位置,移入后其首尾没有一个与相邻的盒子相同。
试探回溯找解算法如下:
算法---试探回溯找解
{
    输入初始排列;
    初始状态存入移动步聚表;
    设置其它初值;
    d=0;        /*当前试探深,或当前状态位置*/
    do
    {
        if(当前状态为盒子排列的终态)
        {
            保存解;
            记录当前解的试探深度;
            回溯;
            if(取尽所有可能的解)break;
        }
        if(试探深度超过设定值,或取尽当前状态的所有选择)
        {
            回溯;
            if(取尽所有可能的选择)break;
        }
        else
        {
            求新状态的空盒位置;
            取当前状态的移动方法和当前状态;
            设定当前状态的下一个移动方法;
            掠过各种不希望的方法;
            生成新状态;
            试探深度增1;
        }
    }while(1);
    if(找到解)
        输出解;
}

程序代码如下:
#include
#include
#define N 30
#define DEPTH 15
char b[2*N+1];
struct node
{
    int empty;        /*两空盒的开始位置*/
    char s[2*N+1];    /*盒子排列*/
    int no;           /*下一个移动开始的位,或称移动方法*/
}q[DEPTH];            /*移动步聚表*/

char result[DEPTH][2*N+1];    /*存放解*/
char *s;
int best,empty,i,j,n,an,bn,sn,c,d;
void main()
{
    printf(" Enter N: ");
    scanf("%d",&n);
    printf("Enter initial state. ");    /*输入初始状态*/
    for(an=bn=sn=i=0;i<2*n;)
    {
        c=getchar();
        if(c==' ')
        {
            if(sn)continue;        /*强制两空白符连续出现*/
            sn=1;
            empty=i;
            b[i++]='_';
            b[i++]='_';
        }
        if(c=='A'c=='a')
        {
           if(an==n-1)continue;    /*限制A的个数*/
           an++;b[i++]='A';
        }
        if(c=='B'c=='b')
        {
            if(bn==n-1)continue;    /*限制B的个数*/
            bn++;b[i++]='B';
        }
    }
    b[2*n]='';
    strcpy(q[0].s,b);        /*初始状态存入移动步聚表*/
    q[0].empty=empty;
    q[0].no=0;
    best=DEPTH-1;            /*设定试探深度*/
    d=0;
    do
    {
        for(s=q[d].s; *s!='B';s++);
        for(;*s&&*s!='A';s++);
        if(*s=='')            /*当前状态为盒子排列的终态*/
        {
            for(j=0;j<=d;j++)        /*保存解*/
                strcpy(result[j],q[j].s);
            best=d;        /*记录当前解的试探深度*/
            d--;            /*回溯*/
            while(d>=0&&q[d].no==2*n-1)d--;
            if(d<0)break;        /*取尽所有可能的选择*/   
        }
        if(d>=bestq[d].no==2*n-1)
        {
            d--;            /*回溯*/            #p#
            while(d>=0&&q[d].no==2*n-1)d--;
            if(d<0)break;        /*取尽所有可能的选择*/
        }
        else
        {
            empty=q[d].empty;    /*新状态的空盒位置*/
            j=q[d].no++;        /*取当前状态的移动方法和设定新移动方法*/
            if(d>=1&&q[d-1].empty==j)continue;    /*掠过来回移动*/
            s=q[d].s;            /*取当前状态*/
            /*掠过各种不希望的移动*/
            if(s[j]=='_'s[j+1]=='_')continue;
            if(j            if(j>empty&&s[j]=='B'&&s[j+1]=='B')continue;
            if(empty!=0&&s[empty-1]!=s[j]&&
               (empty!=2*n-2&&s[empty+2]!=s[j+1]))continue;
            if(empty==0&&s[j]=='B')continue;
            if(empty==2*n-2&&s[j+1]=='A')continue;
                /*生成新状态*/
            strcpy(q[d+1].s,q[d].s);        /*形成移动后的状态*/
            q[d+1].s[empty]=q[d+1].s[j];
            q[d+1].s[empty+1]=q[d+1].s[j+1];
            q[d+1].s[j]=q[d+1].s[j+1]='_';
            q[d+1].empty=j;
            for(j=0;strcmp(q[j].s,q[d+1].s);j++);
            if(j<=d)continue;
            q[d+1].no=0;
            d++;            /*试探深度增1*/
        }
    }while(1);
    if(best!=DEPTH-1)
    {
        printf(" ");
        for(j=0;j<=best;j++)
            printf("%s ",result[j]);
    }
}

 

上下文章:

 

上一篇文章: 全国计算机等级考试二级Access考试(样题) 下一篇文章: 计算机二级:C程序设计例解(06)

相关文章:

  • 中国国家计算机病毒中心监测发现蠕虫新变种
  • 09年全国计算机等级考试更新7门教材
  • 确保计算机安全 个人用户责无旁贷
  • 计算机病毒中心:重视微软高危漏洞补丁程序
  • 微软第二代超级计算机版Windows发布在即

相关软件:

  • 二级VB学习系统 1.0
  • 计算机等级考试训练模拟软件(三级数据库技术) V1.01
  • C/C++程序设计学习与实验系统 2008.14
  • 全国计算机等级考试二级VFP上机考试模拟 V1.0
  • 全国计算机等级考试模拟软件(2006年全年使用)二级Visual Basic V9.0
  • 全国计算机等级考试第21次全真模拟系统 20050311

 

快速导航

  • 网络学院
  • 精品汇聚
  • 字体下载
  • 教程下载
  • ASP源码
  • PHP源码
  • Net源码
  • JSP 源码

计算机等级考试分类导航

  • 计算机等级考试动态
  • 计算机一级考试
  • 计算机二级考试
  • 计算机三级考试
  • 计算机四级考试

本类经典文章推荐

  • 2006年全国计算机等级考试二级C考...
  • 《C++编程规范》笔记(设计风格)
  • 如何编写高质量的VB代码
  • VB编程的几个API函数的应用问题
  • VB编程:去掉窗体的关闭按钮
  • 最简Windows编程
  • VB编程:如何在列表框中自动查找
  • VB指导:生成auto-OK对话框
  • 使用VB的布局工具节省编程时间
  • VB中利用Winrar进行文件压缩

计算机二级考试阅读排行

  • 计算机二级:《计算机基础》考试题
  • 2006年全国计算机等级考试二级C考...
  • VB编程:去掉窗体的关闭按钮
  • 计算机二级:计算机基础知识作业题
  • 二级VF程序设计全真预测试卷(一)
  • 全国计算机等级考试二级VISUALFOX...
  • 2005年9月17日二级VF笔试试题答案
  • 《C++编程规范》笔记(设计风格)
  • 二级C语言程序设计试题(含答案)
  • 2005年9月计算机等级考试二级笔试...

计算机等级考试阅读总排行

  • 全国计算机等级考试一级模拟试题01
  • 全国计算机等级考试一级模拟试题10
  • 全国计算机等级考试一级模拟试题08
  • 全国计算机等级考试一级模拟试题02
  • 全国计算机等级考试一级考试最新模...
  • 全国计算机等级考试一级模拟试题07
  • 一级(WINDOWS)试题解析-Word篇
  • 全国计算机等级考试上机考试应试技...
  • 全国计算机等级考试一级模拟试题03
  • 全国计算机等级考试一级模拟试题06

广告位置

字母检索 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 回到顶部

关于我们 | 版权声明 | 免责条款 | 广告联系 | 软件发布 | 下载帮助 | 下载排行 | 网站地图 | 特别鸣谢 | 友情连接

copyright; 2005-2008 D9soft.com 第九软件网 版权所有