1、武汉理工大学暑期基础强化训练学 号: 课 程 设 计(基础强化训练)题 目Sticks学 院计算机科学与技术专 业软件工程班 级软件1101姓 名指导教师2013年7月12日课程设计任务书学生姓名: 专业班级: 软件1101 指导教师: 工作单位:计算机科学与技术学院题 目: Sticks 初始条件: 乔治把相同的长度的棍棒切割直到每部分小棍最长不超过50单位。现在他想返回棍棒到原来的状态,但他忘了原本有多少棍棒和棍棒原本的长度。请帮他设计一个程序,计算最原始棍棒的最小长度。所有用单位表示的长度都是大于零的整数。 输入:输入包含2条线块。第一行包含切割后的小棍数,最多有64支。第二行包含被切割
2、后各个小棍的长度。输入的最后一行包含零。 输出:输出应该包含原始木棍可能的最小长度,每行一个。 要求完成的主要任务: (包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1、完成算法分析2、给出对应的程序流程图3、给出能正确实现的程序源码5、给出试算截屏图6、课程设计工作的分析与总结7、给出不少于5篇参考文献。时间安排:20013-7-8到20013-7-12消化资料、系统调查、形式描述 1天系统分析、总体设计、实施计划 3天撰写课程设计报告书 1天 指导教师签名: 2013年 7 月 8 日系主任(或责任教师)签名: 2013年 7 月 8 日目录1、注册资料12、选题描述13、算法
3、分析24、程序流程图75、程序源码86、试算截屏图127、分析与总结138、参考文献15Sticks 1、注册资料用户名:密码:选题题号:10112、选题描述 乔治把相同的长度的棍棒切割直到每部分小棍最长不超过50单位。现在他想返回棍棒到原来的状态,但他忘了原本有多少棍棒和棍棒原本的长度。请帮他设计一个程序,计算最原始棍棒的最小长度。所有用单位表示的长度都是大于零的整数。 输入:输入包含2条线块。第一行包含切割后的小棍数,最多有64支。第二行包含被切割后各个小棍的长度。输入的最后一行包含零。 输出:输出应该包含原始木棍可能的最小长度,每行一个。举例说明: 输入:9 5 2 1 5 2 1 5
4、2 1 4 1 2 3 4 0 输出:6 53、算法分析3.1对小棍进行排序首先,定义数组l642来存储小棍的相关信息,并且依据小棍的长度进行由大到小的排序。并且给每一个小棍加上指针,指向下一个长度不同的小棍。因此有代码:void sort() /对小棍进行排序 for (int i=0;in;i+) for (int j=i+1;jn;j+) if (li0lj0) int t=li0; li0=lj0; lj0=t; /给每一个小棍加上指针,指向下一个长度不同的小棍 int i=0; while (in) int j=i+1; while (jn&lj0=li0) j+; for (int
5、 k=i;kj;k+) lk1=j; i=j; 3.2计算一个指针,其后小棍相加之和大约为一根原棍长度 首先用一数组标USED记某一小棍在当前状态下是否已经被用于组合原棍。初始化设置所有小棍均未使用,然后计算一个指针,其后小棍相加之和大约为一根原棍长度。这一段代码为:void initial() /初始化设置所有小棍均未使用 for (int i=0;i=0;i-) sumr+=li0; if (sumrlen) break; tail=i;3.3计算下标大于等于m且未使用的小棍总长之和 计算下标大于等于m且未使用的小棍总长之和,因此有代码:inline int sumres(int m) /
6、计算下标大于等于m且未使用的小棍总长之和 int sumr=0; for (int i=m;in;i+) if (usedi=false) sumr+=li0; return sumr;3.4深度优先搜索 由小到大枚举所有可能的原棍长度,通过深度优先搜索尝试小棍能否组合成原棍,一旦检验成功则算法结束,当前原棍长度即为最小可能原棍长度。 枚举过程如下,设小棍的总长为SUM,最长小棍长度为MAX,从MAX开始由小到大枚举原棍长度LEN,使得LEN能被SUM整除。然后进行搜索,尝试用所有小棍拼出SUM/LEN根的原棍。搜索过程如下,首先用一数组标USED记某一小棍在当前状态下是否已经被用于组合原棍,
7、另有有两个主要参数表示搜索时的状态,CPL表示已经组合好的原棍数,RES表示当前正在组合的原棍(以下称当前原棍)已组合出的长度。在每一种状态下,尝试所有可能拼接在当前原棍上的未使用的小棍,即将满足USED=FALSE且RES+Li=LEN的小棍接入当前原棍,传递RES的参数RES+Li,若RES+Li=LEN,传递CPL的参数CPL+1,否则,传递CPL,同时令USED=TRUE,然后进行递归,进入下一层搜索。退出下层递归后,将USED重新赋为FALSE。当CPL=SUM/LEN时,返回TRUE,表示搜索成功,一旦下一层递归返回TRUE,当前递归也返回TRUE,不断返回,直到跳出函数调用,表示
8、当前原棍长度为可行解,且为最小,输出。因此有代码:bool search(int res,int next,int cpl)/策略2:用next存储当前可用的下一支小棍 /修正参数,当res=len时表示正好拼接成一支原棍 if (res=len) res=0; next=1; cpl+; /当已拼出的原棍为应拼出原棍时,返回TRUE if (cpl=parts) return true; int i=next; while (in) /尝试未使用的小棍 if (usedi=false) /判断接入此小棍是否超出原棍长度 if (res+li0=tail&sumres(i)len-res) b
9、reak; continue; i+; return false;int main() while (scanf(%d,&n),n!=0) /输入 sum=0; for (int i=0;in;i+) scanf(%d,&li0); sum+=li0; /策略1:按小棍长度排序 sort(); max=l00; for (len=max;len=sum;len+) /枚举原棍长度,并判断其能否整除总长度 if (sum%len=0) parts=sum/len; initial(); if (search(0,0,0) printf(%dn,len); break; return 0; 4、程
10、序流程图5、程序源码#include int n; /小棍总数int len; /当前枚举的原棍长度int parts; /当前组合的原棍数int max; /最长小棍的长度int sum; /所有小棍的总长int tail; /指向尾部长度较小的棍int l642; /存储小棍相关信息bool used64; /标记小棍是否使用void sort() /对小棍进行排序 for (int i=0;in;i+) for (int j=i+1;jn;j+) if (li0lj0) int t=li0; li0=lj0; lj0=t; /给每一个小棍加上指针,指向下一个长度不同的小棍 int i=0
11、; while (in) int j=i+1; while (jn&lj0=li0) j+; for (int k=i;kj;k+) lk1=j; i=j; void initial() /初始化设置所有小棍均未使用 for (int i=0;i=0;i-) sumr+=li0; if (sumrlen) break; tail=i;inline int sumres(int m) /计算下标大于等于m且未使用的小棍总长之和 int sumr=0; for (int i=m;in;i+) if (usedi=false) sumr+=li0; return sumr;bool search(int res,int next,int cpl)/
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1