武汉理工大学暑期基础强化训练.docx

上传人:b****3 文档编号:2843383 上传时间:2022-11-15 格式:DOCX 页数:16 大小:91.11KB
下载 相关 举报
武汉理工大学暑期基础强化训练.docx_第1页
第1页 / 共16页
武汉理工大学暑期基础强化训练.docx_第2页
第2页 / 共16页
武汉理工大学暑期基础强化训练.docx_第3页
第3页 / 共16页
武汉理工大学暑期基础强化训练.docx_第4页
第4页 / 共16页
武汉理工大学暑期基础强化训练.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

武汉理工大学暑期基础强化训练.docx

《武汉理工大学暑期基础强化训练.docx》由会员分享,可在线阅读,更多相关《武汉理工大学暑期基础强化训练.docx(16页珍藏版)》请在冰豆网上搜索。

武汉理工大学暑期基础强化训练.docx

武汉理工大学暑期基础强化训练

学号:

课程设计

(基础强化训练)

 

题目

Sticks

学院

计算机科学与技术

专业

软件工程

班级

软件1101

姓名

指导教师

 

2013

7

12

课程设计任务书

学生姓名:

专业班级:

软件1101

指导教师:

工作单位:

计算机科学与技术学院

题目:

Sticks

初始条件:

乔治把相同的长度的棍棒切割直到每部分小棍最长不超过50单位。

现在他想返回棍棒到原来的状态,但他忘了原本有多少棍棒和棍棒原本的长度。

请帮他设计一个程序,计算最原始棍棒的最小长度。

所有用单位表示的长度都是大于零的整数。

输入:

输入包含2条线块。

第一行包含切割后的小棍数,最多有64支。

第二行包含被切割后各个小棍的长度。

输入的最后一行包含零。

输出:

输出应该包含原始木棍可能的最小长度,每行一个。

要求完成的主要任务:

(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)

1、完成算法分析

2、给出对应的程序流程图

3、给出能正确实现的程序源码

5、给出试算截屏图

6、课程设计工作的分析与总结

7、给出不少于5篇参考文献。

时间安排:

20013-7-8到20013-7-12

消化资料、系统调查、形式描述1天

系统分析、总体设计、实施计划3天

撰写课程设计报告书1天

 

指导教师签名:

2013年7月8日

系主任(或责任教师)签名:

2013年7月8日

 

目录

1、注册资料………………………………………………………………………………1

2、选题描述………………………………………………………………………………1

3、算法分析………………………………………………………………………………2

4、程序流程图……………………………………………………………………………7

5、程序源码………………………………………………………………………………8

6、试算截屏图……………………………………………………………………………12

7、分析与总结……………………………………………………………………………13

8、参考文献………………………………………………………………………………15

Sticks

1、注册资料

用户名:

密码:

选题题号:

1011

 

2、选题描述

乔治把相同的长度的棍棒切割直到每部分小棍最长不超过50单位。

现在他想返回棍棒到原来的状态,但他忘了原本有多少棍棒和棍棒原本的长度。

请帮他设计一个程序,计算最原始棍棒的最小长度。

所有用单位表示的长度都是大于零的整数。

输入:

输入包含2条线块。

第一行包含切割后的小棍数,最多有64支。

第二行包含被切割后各个小棍的长度。

输入的最后一行包含零。

输出:

输出应该包含原始木棍可能的最小长度,每行一个。

举例说明:

输入:

9

521521521

4

1234

0

输出:

6

5

 

3、算法分析

3.1对小棍进行排序

首先,定义数组l[64][2]来存储小棍的相关信息,并且依据小棍的长度进行由大到小的排序。

并且给每一个小棍加上指针,指向下一个长度不同的小棍。

因此有代码:

voidsort(){

//对小棍进行排序

for(inti=0;i

{

for(intj=i+1;j

{

if(l[i][0]

{

intt=l[i][0];

l[i][0]=l[j][0];

l[j][0]=t;

}

}

}

//给每一个小棍加上指针,指向下一个长度不同的小棍

inti=0;

while(i

{

intj=i+1;

while(j

for(intk=i;k

i=j;

}

}

3.2计算一个指针,其后小棍相加之和大约为一根原棍长度

首先用一数组标USED[]记某一小棍在当前状态下是否已经被用于组合原棍。

初始化设置所有小棍均未使用,然后计算一个指针,其后小棍相加之和大约为一根原棍长度。

这一段代码为:

voidinitial(){

//初始化设置所有小棍均未使用

for(inti=0;i

{

used[i]=false;

}

intsumr=0;

//计算一个指针,其后小棍相加之和大约为一根原棍长度

inti=n-1;

for(inti=n-1;i>=0;i--)

{

sumr+=l[i][0];

if(sumr>len)break;

}

tail=i;

}

3.3计算下标大于等于m且未使用的小棍总长之和

计算下标大于等于m且未使用的小棍总长之和,因此有代码:

inlineintsumres(intm){

//计算下标大于等于m且未使用的小棍总长之和

intsumr=0;

for(inti=m;i

if(used[i]==false)

sumr+=l[i][0];

}

returnsumr;

}

3.4深度优先搜索

由小到大枚举所有可能的原棍长度,通过深度优先搜索尝试小棍能否组合成原棍,一旦检验成功则算法结束,当前原棍长度即为最小可能原棍长度。

枚举过程如下,设小棍的总长为SUM,最长小棍长度为MAX,从MAX开始由小到大枚举原棍长度LEN,使得LEN能被SUM整除。

然后进行搜索,尝试用所有小棍拼出SUM/LEN根的原棍。

搜索过程如下,首先用一数组标USED[]记某一小棍在当前状态下是否已经被用于组合原棍,另有有两个主要参数表示搜索时的状态,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,不断返回,直到跳出函数调用,表示当前原棍长度为可行解,且为最小,输出。

因此有代码:

boolsearch(intres,intnext,intcpl)

//策略2:

用next存储当前可用的下一支小棍

{

//修正参数,当res=len时表示正好拼接成一支原棍

if(res==len){

res=0;

next=1;

cpl++;

}

//当已拼出的原棍为应拼出原棍时,返回TRUE

if(cpl==parts)

returntrue;

inti=next;

while(i

//尝试未使用的小棍

if(used[i]==false){

//判断接入此小棍是否超出原棍长度

if(res+l[i][0]<=len){

//将该小棍标为已使用

used[i]=true;

//递归搜索,一旦成功则不断向上一级返回TRUE

if(search(res+l[i][0],i+1,cpl))returntrue;

//还原该小棍为未使用

used[i]=false;

//策略4:

第一次拼接当前原棍无解则当前状态必定无解,跳出

if(res==0)break;

//策略5:

若尝试一根小棍恰能组合出当前原棍的剩余长度的小棍失败,则不再尝试比它更小的小棍

if(res+l[i][0]==len)break;

}

//策略3:

若使用当前小棍无解则尝试下一支长度不同的小棍

i=l[i][1];

//策略6:

计算当前所剩可用小棍是否足以拼出当前这支木棍原型

if(i>=tail&&sumres(i)

continue;

}

i++;

}

returnfalse;

}

intmain(){

while(scanf("%d",&n),n!

=0){

//输入

sum=0;

for(inti=0;i

scanf("%d",&l[i][0]);

sum+=l[i][0];

}

//策略1:

按小棍长度排序

sort();

max=l[0][0];

for(len=max;len<=sum;len++){

//枚举原棍长度,并判断其能否整除总长度

if(sum%len==0){

parts=sum/len;

initial();

if(search(0,0,0)){

printf("%d\n",len);

break;

}

}

}

}

return0;

}

 

4、程序流程图

 

5、程序源码

#include

intn;//小棍总数

intlen;//当前枚举的原棍长度

intparts;//当前组合的原棍数

intmax;//最长小棍的长度

intsum;//所有小棍的总长

inttail;//指向尾部长度较小的棍

intl[64][2];//存储小棍相关信息

boolused[64];//标记小棍是否使用

voidsort(){

//对小棍进行排序

for(inti=0;i

{

for(intj=i+1;j

{

if(l[i][0]

{

intt=l[i][0];

l[i][0]=l[j][0];

l[j][0]=t;

}

}

}

//给每一个小棍加上指针,指向下一个长度不同的小棍

inti=0;

while(i

{

intj=i+1;

while(j

for(intk=i;k

i=j;

}

}

voidinitial(){

//初始化设置所有小棍均未使用

for(inti=0;i

{

used[i]=false;

}

intsumr=0;

//计算一个指针,其后小棍相加之和大约为一根原棍长度

inti=n-1;

for(inti=n-1;i>=0;i--)

{

sumr+=l[i][0];

if(sumr>len)break;

}

tail=i;

}

inlineintsumres(intm){

//计算下标大于等于m且未使用的小棍总长之和

intsumr=0;

for(inti=m;i

if(used[i]==false)

sumr+=l[i][0];

}

returnsumr;

}

boolsearch(intres,intnext,intcpl)

//

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1