数据结构课程设计.docx

上传人:b****2 文档编号:14465620 上传时间:2023-04-23 格式:DOCX 页数:23 大小:192.36KB
下载 相关 举报
数据结构课程设计.docx_第1页
第1页 / 共23页
数据结构课程设计.docx_第2页
第2页 / 共23页
数据结构课程设计.docx_第3页
第3页 / 共23页
数据结构课程设计.docx_第4页
第4页 / 共23页
数据结构课程设计.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

数据结构课程设计.docx

《数据结构课程设计.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计.docx(23页珍藏版)》请在冰豆网上搜索。

数据结构课程设计.docx

数据结构课程设计

学号

201110137133

 

武汉科技大学城市学院

 

课程设计报告

 

课程名称数据结构课程设计

题目

ACM题型设计

学部

信息工程学部

专业

计算机科学与技术

班级

一班

姓名

指导教师

杨艳霞

2013

7

5

目录

题目一喷水装置

(一)1

1题目要求1

2算法设计思路及步骤2

3算法描述3

4结果分析4

题目二阶乘的05

1题目要求5

2算法设计思路及步骤6

3算法描述7

4结果分析8

题目三找球号

(一)8

1题目要求8

2算法设计思路及步骤9

3算法描述10

4结果分析11

题目四ASCII码排序12

1题目要求12

2算法设计思路及步骤13

3算法描述13

4结果分析15

题目五会场安排问题16

1题目要求16

2算法设计思路及步骤17

3算法描述17

4结果分析19

小结20

参考文献21

题目一喷水装置

(一)

1题目要求

1.1问题描述

现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0

选择尽量少的喷水装置,把整个草坪的全部湿润。

时间限制:

3000ms|内存限制:

65535KB。

1.2输入

第一行m表示有m组测试数据,每一组测试数据的第一行有一个整数数n,n表示共有n个喷水装置,随后的一行,有n个实数ri,ri表示该喷水装置能覆盖的圆的半径。

1.3输出

输出所用装置的个数。

1.4样例输入

2

5

23.244.56

10

123121.231.112

1.5样例输出

2

5

2算法设计思路及步骤

2.1设计思路

这是一个3级难度的题,看起来着题目不知从何下手。

我仔细想了想,发现,只要算出这个草地的斜边长度,然后只要全部圆的半径合大于等于这个斜边长度的一半就可以了。

不过必须舍弃半径小于等于1的装置,在草坪中线上无论怎么放,它是无法完全覆盖整个草坪的。

如图2.1:

x=sqrt(r*r-(h/2)*(h/2)), 这样半径为r的圆能够覆盖的长度为2x, 剩下w-2x,这样遍历下去,当w<=0时,就满足了。

  

简化一下,就是求全部圆的半径(小于等于1的不算)和大于等于这个斜边长度的一半。

r=sqrt(x*x+h*h)/2;总的半径和ra=sqrt(w*w+h*h)/2

 

图1.1喷水装置示意图

2.2步骤

1)建立int型变量m,通过scanf接受用户输入m组测试数据,从而控制程序循环的次数。

2)建立一个double型数组buf[600],用于存放每个喷水装置能覆盖圆的半径。

3)建立double型变量len,并计算出草地斜边长度的一半。

4)While循环,控制测试组数,是输入m组测试数据。

5)调用系统快速排序方法对半径排序,compare方法是指向函数的指针,是作为qsort的参数,用于确定快速排序的顺序。

6)sum变量用于存放半径和。

7)当半径和大于等于草地斜边长度一半就满足条件了。

8)printf输入所用装置个数.

3算法描述

#include

#include

#include

//指向函数的指针,用于确定快速排序的顺序

intcompare(constvoid*a,constvoid*b)

{

return*(double*)b>*(double*)a?

1:

-1;

}

intmain()

{

intm;

scanf("%d",&m);//输入m组测试数据

doublebuf[600];//存放每个喷水装置能覆盖圆的半径

doublelen=sqrt(20*20+2*2)/2;//草地斜边长度的一半

while(m--)

{

intn,i;

scanf("%d",&n);//输入n个喷水装置

for(i=0;i

scanf("%lf",buf+i);//输入n个喷水装置能覆盖圆的半径

qsort(buf,n,sizeof(buf[0]),compare);//调用系统的快速排序方法对圆半径排序

doublesum=0;//存放半径和

for(i=0;i

{

if(buf[i]<=1)

break;

sum+=buf[i];

if(sum>=len)//半径和大于等于草地斜边长度一半就满足条件了

break;

}

printf("%d\n",i+1);

}

return0;

}return0;

}

4结果分析

这是一个3级的题目,初次做ACM系统的题目,在VC++6.0编译器里运行通过的程序,提交到ACM系统时,经常报错。

多数情况是内存或时间超出题目的限制或程序的输入输出格式没严格按照题目的意思来。

经过改进程序的算法和优化代码,严格按照题目要求的格式输入或输出等,再提交到ACM系统时,终于成功的通过了。

图1.2喷水装置ACM结果

图1.3喷水装置运行

当然,拿下这个题目我花了不少精力,通过XX,我了解了怎样调用系统的快速排序方法,虽然它的参数很多。

题目二阶乘的0

1题目要求

1.1问题描述

计算n!

的十进制表示最后有多少个0。

时间限制:

3000ms|内存限制:

65535KB。

1.2输入

第一行输入一个整数N表示测试数据的组数(1<=N<=100)

每组测试数据占一行,都只有一个整数M(0<=M<=10000000)

1.3输出

输出M的阶乘的十进制表示中最后0的个数

比如5!

=120则最后的0的个数为1

1.4样例输入

6

3

60

100

1024

23456

8735373

1.5样例输出

0

14

24

253

5861

2183837

2算法设计思路及步骤

2.1设计思路

这个题看似简单,其实不怎么好下手。

一个数n的阶乘末尾有多少个0取决于从1到n的各个数的因子中2和5的个数,而2的个数是远远多余5的个数的,因此求出5的个数即可.题解中给出的求解因子5的个数的方法是用n不断除以5,直到结果为0,然后把中间得到的结果累加.例如,100/5=20,20/5=4,4/5=0,则1到100中因子5的个数为(20+4+0)=24个,即100的阶乘末尾有24个0.其实不断除以5,是因为每间隔5个数有一个数可以被5整除,然后在这些可被5整除的数中,每间隔5个数又有一个可以被25整除,故要再除一次,直到结果为0,表示没有能继续被5整除的数了。

2.2步骤

1)建立int型变量N,并从键盘输入N,表示有N组测试数据。

2)While循环,控制测试组数,由N决定循环次数。

3)循环里面要求输入测试整数M,并建立变量sum。

4)内层循环累加M除5的结果,直到M/5结果为0。

5)printf输入结果。

3算法描述

#include

intmain()

{

intN;

scanf("%d",&N);//N组测试数据

while(--N)

{

intM;

scanf("%d",&M);//测试整数M

intsum=0;

while(M)//累加M除5的结果

{

sum=sum+M/5;

M=M/5;

}

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

}

return0;

}

4结果分析

这个题的难度为3级,代码其实很简单,也很容易理解,但刚开始我也不知该怎么下手。

然后,我就在网上找资料,发现原来与5有关。

但第一次做出来,在VC++6.0环境下运行没问题,提交到ACM系统提示“TimeLimitExceeded”,时间超标,题目要求时间限制:

3000ms|内存限制:

65535KB。

于是我优化代码,但效果不明显。

最后,我请大神帮我优化,结果终于出来了,这题目费了九牛二虎之力啊。

图2.1阶乘的0ACM结果

图2.2阶乘的0结果

题目三找球号

(一)

1题目要求

1.1问题描述

在某一国度里流行着一种游戏。

游戏规则为:

在一堆球中,每个球上都有一个整数编号i(0<=i<=100000000),编号可重复,现在说一个随机整数k(0<=k<=100000100),判断编号为k的球是否在这堆球中(存在为"YES",否则为"NO"),先答出者为胜。

现在有一个人想玩玩这个游戏,但他又很懒。

他希望你能帮助他取得胜利。

时间限制:

3000ms,内存限制:

65535KB。

1.2输入

第一行有两个整数m,n(0<=n<=100000,0<=m<=1000000);m表示这堆球里有m个球,n表示这个游戏进行n次。

接下来输入m+n个整数,前m个分别表示这m个球的编号i,后n个分别表示每次游戏中的随机整数k。

1.3输出

输出"YES"或"NO"。

1.4样例输入

64

233446768343343

2423343

1.5样例输出

NO

NO

YES

YES

2算法设计思路及步骤

2.1设计思路

这个题目的设计思路是先调用系统的快排序,对球堆序列进行排序。

然后调用系统的二分查找法,判断k的球是否在这堆球中。

通过调用系统的方法,能够保证程序的时间复杂度符合ACM系统的要求。

2.2步骤

1)建立int型变量m,n,m表示这堆球里有m个球,n表示这个游戏进行n次。

2)int型数字a[]10001],用于存放球堆编号。

3)compare方法,比较函数,用于二分查找和快速排序的参数。

4)qsort调用系统的快速排序,对球堆排序,用于后面的查找,。

5)for循环里面的bsearch是调用系统的二分查找,判断k球是否在球堆序列。

6)printf输入判断的结果。

3算法描述

#include

#include

intcompare(constvoid*a,constvoid*b)//比较函数,用于二分查找和快速排序的参数

{

return*(int*)a-*(int*)b;

}

intmain()

{

intm,n;//球堆里有m个球,游戏进行n次

inta[10001];

intt;

scanf("%d%d",&m,&n);

for(inti1=0;i1

{

scanf("%d",&a[i1]);

}

qsort(a,m,sizeof(int),compare);//快速排序,对球堆排序,用于后面的查找

for(inti2=0;i2

{

scanf("%d",&t);

void*p=bsearch(&t,a,m,sizeof(int),compare);//二分查找,判断k球是否在球堆序列

if(p)

printf("YES\n");

else

printf("NO\n");

}

return0;

}

4结果分析

要保证题目提交到ACM系统能通过,我自己写的快速排序和二分查找,怎么也通过不了,调用系统的方法才是王道啊,这样才能不超过时间限制,避免“TimeLimitExceede”。

原来系统里的方法执行效率是如此之高。

代码里主要就是调用系统的快速排序和二分查找方法,2个方法的参数都比较多,用法好似参考的网络。

图3.1找球号ACM结果

图3.2找球号运行结果

题目四ASCII码排序

1题目要求

1.1问题描述

输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符。

时间限制:

3000ms,内存限制:

65535KB。

1.2输入

第一行输入一个数N,表示有N组测试数据。

后面的N行输入多组数据,每组输入数据都是占一行,由三个字符组成,之间无空格。

1.3输出

对于每组输入数据,输出一行,字符中间用一个空格分开。

1.4样例输入

3

qwe

asd

zxc

1.5样例输出

eqw

ads

cxz

2算法设计思路及步骤

2.1设计思路

这是我做的第一个ACM系统的题目。

在VC++6.0的环境下,通过的程序,提交到ACM系统,不一定能通过。

ACM系统要考虑时间复杂度,空间复杂度,还有输入、输出格式,以及main方法返回值,C++的代码还得考虑命名空间的问题。

这些都有严格的要求。

题目思路挺简单,就是对各组字符按ASCⅡ码排序。

2.2步骤

1)建立int型变量N,使用cin来接收用户输入的测试数据组数。

2)建立2个char型指针*s,*ps,s用于存放输入的ASCⅡ码,ps用于交换数据时记录位置的指针。

3)for循环判定ASCⅡ码大小并排序,循环次数由数据组数N决定。

4)for循环里面的第一个if用于判断每组的第一个ASCⅡ码和第二个ASCⅡ码的大小。

5)for循环里面的第二个if用于判断每组的第一个ASCⅡ码和第三个ASCⅡ码的大小。

6)for循环里面的第三个if用于判断每组的第二个ASCⅡ码和第三个ASCⅡ码的大小。

7)for循环里的cout输出每组的结果。

3算法描述

#include

#include

#include

usingnamespacestd;

intmain()

{

intN,i;

char*s,*ps;

cin>>N;//输入测试数据组数

s=(char*)malloc(sizeof(char)*3*N);//分配存储空间

ps=s;

for(i=1;i<=N;i++)//输入多组数据

{

scanf("%s",&ps[3*i-3]);

}

for(i=1;i<=N;i++)//判断ASCⅡ码大小并排序

{

if(ps[3*i-3]>ps[3*i-2])

{

ps[3*i-2]=ps[3*i-2]^ps[3*i-3];

ps[3*i-3]=ps[3*i-2]^ps[3*i-3];

ps[3*i-2]=ps[3*i-2]^ps[3*i-3];

}

if(ps[3*i-3]>ps[3*i-1])

{

ps[3*i-1]=ps[3*i-1]^ps[3*i-3];

ps[3*i-3]=ps[3*i-1]^ps[3*i-3];

ps[3*i-1]=ps[3*i-1]^ps[3*i-3];

}

if(ps[3*i-2]>ps[3*i-1])

{

ps[3*i-1]=ps[3*i-1]^ps[3*i-2];

ps[3*i-2]=ps[3*i-1]^ps[3*i-2];

ps[3*i-1]=ps[3*i-1]^ps[3*i-2];

}

cout<

}

return0;

}

4结果分析

这也是一个2级难度的题,在编译器里运行通过的程序,第一次提交时ACM系统却给出了错误提示:

TimeLimitExceede(超时)。

题目要求有时间限制:

3000ms,内存限制:

65535KB。

然后改进

现在必须考虑时间复杂度了。

经过改进,我用的一层循环,里面用几个if语句判断,提高了时间复杂度,通过了ACM系统:

图3.1ASCII码排序ACM结果

图3.2ASCII码排序运行结果

题目五会场安排问题

1题目要求

1.1问题描述

学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办。

小刘的工作就是安排学校小礼堂的活动,每个时间最多安排一个活动。

现在小刘有一些活动计划的时间表,他想尽可能的安排更多的活动,请问他该如何安排。

时间限制:

3000ms,内存限制:

65535KB。

1.2输入

第一行是一个整型数m(m<100)表示共有m组测试数据。

每组测试数据的第一行是一个整数n(1

随后的n行,每行有两个正整数Bi,Ei(0<=Bi,Ei<10000),分别表示第i个活动的起始与结束时间(Bi<=Ei)。

1.3输出

对于每一组输入,输出最多能够安排的活动数量。

每组的输出占一行。

1.4样例输入

2

2

110

1011

3

110

1011

1120

1.5样例输出

1

2

2算法设计思路及步骤

2.1设计思路

这是个4级难度的题目,对我来说,难度挺大的。

这样的题时间复杂度总是成问题,每次提交到ACM系统,总是TimeLimitExceede。

这个题也不例外,自己写的方法,跑起来总是时间超标。

不得不调用系统的方法,看来调用系统的方法也是一个很好的方法,既不用自己写方法,也提高了效率。

2.2步骤

1)建立结构体Activity,用于存放每个活动的开始时间和结束时间,便于后边的操作。

2)建立一个int型m,表示m组测试数据,并从键盘输入。

3)使用while语句控制测试次数,由m决定。

4)While里面的for循环用于接收输入的活动时间。

5)compare方法,用于快速排序的参数

6)调用系统的快速排序qsort,对活动按时间先后排序。

7)第二个for循环,选择安排进行的活动,并统计能安排的活动的个数。

8)printf输出结果。

3算法描述

#include

#include

#include

usingnamespacestd;

structActivity//活动时间结构体

{

intbegin;

intend;

}A[10000];

intcompare(constvoid*a,constvoid*b)//用于快速排序的参数

{

structActivity*c=(Activity*)a;

structActivity*d=(Activity*)b;

returnc->end-d->end;

}

intmain()

{

intm;//m组测试数据

inti,j=0,count=1;

scanf("%d",&m);

while(--m)

{

intn,i;

scanf("%d",&n);

for(i=0;i

{

scanf("%d%d",&A[i].begin,&A[i].end);//将比赛时间用结构体粗放

}

qsort(A,n,sizeof(A[0]),compare);

for(i=1;i

{

if(A[i].begin>A[j].end)

{

count++;

j=i;

}

}

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

}

}

4结果分析

4级难度的题目与3级难度的题目还是有很多区别的,对于时间的控制更加严格,一不小心时间就超标了。

这个题目也花了不少时间,一开始,我没调用系统的方法,都是自己写的方法,提交到ACM系统,总是TimeLimitExceede,最后不得不调用系统的方法,看来调用系统的方法也是一个很好的方法,既不用自己写方法,也提高了效率。

图4.1会场安排ACM结果

图4.2会场安排运行结果

小结

我们用了一周的时间做这次数据结构的课程设计,对于我来说,这时间挺紧的。

我做的是南洋理工学院的ACM系统的题目。

这也是我第一次接触OJ系统。

上面的题目我只能做3级难度的,而且每个3级的的题目我都要花不少时间,做4级的题目时,经常是时间超过了题目的规定。

ACM系统的题目整体的代码都比较简短,但算法需要花费精力思考,题目都是生活中的实际问题。

在这次课程设计中,使我懂得了理论与实际相结合是非常重要的。

只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能提高自己的思考和解决问题以及实际动手能力。

同时也巩固和加深了我对数据结构的进一步掌握,提高综合运用本课程所学知识的能力,培养了我运用参考书,查阅手册及文献资料的能力,培养独立思考,深入研究,分析问题,解决问题的能力。

通过实际对编译系统的分析设计,编程调试,掌握应用软件的分析方法和设计方法。

通过这次做ACM,我对数据结构有了更深的了解。

我觉得ACM系统的要求很严,刚做第一个题的时候觉得很不适应。

我觉得ACM很好的提高了我们写程序时的严谨性,使得我们不能随意的书写。

另外ACM里面都是对一些现实问题的抽象,不是单纯的题目,要求我们能够建立模型,然后根据简单的数据结构写出程序。

我觉得我们应该加强ACM的训练,这样有利于我们更好地掌握所学的知识,可以提高我们的综合素质。

我也认识到自己还有很多很多不会的,特别是算法,都不注重时间复杂度和空间复杂度,像现在流行的Android系统,内存有限,CPU效率也有限,时间复杂度和空间复杂度都是非常重要的。

我想,我以后要经常做做ACM系统的题,掌握更多的、优秀的算法与数据结构。

参考文献

[1]严蔚敏,吴伟民.数据结构(C语言版).清华大学出版社,2011.

[2]刘振安,刘燕君.C程序设计课程设计[M].北京:

机械工业出版社,2004.

[3]谭浩强.C程序设计(第三版).清华大学出版社,2010.

[4]吴文虎.程序设计基础.清华大学出版社,2010.

[5]严蔚敏,陈文博.数据结构及应用算法教程.清华大学出版社,2004.

课设计评分表

评分标准:

1.学生是否严格遵守课程设计纪律,按照规定时间完成设计任务(占30%)

2.程序设计的质量与规范:

(占40%)

(1)选题难度:

ACM题目(A级或B级)、传统题目

(2)是否采用了良好的设计方法

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

当前位置:首页 > 表格模板 > 合同协议

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

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