猴子吃桃问题

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

软件综合课程设计
猴子吃桃问题
学生搭配问题
二〇一四年六月
《猴子吃桃子课程设计》报告
一、问题陈述
猴子吃桃子问题:
有一群猴子摘了一堆桃子,他们每天都吃当前桃子的一半且再多吃一个,到了第10天就只余下一个桃子。

用多种方法实现求出原来这群猴子共摘了多少个桃子。

二、需求分析
要求:1.采用数组数据结构实现上述求解;
2.采用链数据结构实现上述求解;
3.采用递归实现上述求解。

三、概要设计
四、详细设计
猴子每天都吃当前桃子的一半多一个,假设今天还有n个桃子,则前一天就有(n+1)*2个桃子。

又已知第十天只剩下一个桃子,则可代入以上公式求出第九天的桃子数,以此类推求下去便可得到第一天的桃子数。

1.采用数组数据结构实现上述求解
声明一个长度为10的整形数组arr[10],分别存放各天猴子吃前的桃子数。

下图所示
arr[0] arr[1]arr[2]arr[3] arr[4]arr[5]arr[6]arr[7] arr[8]arr[9]先将arr[9]赋值为1,用一个循环语句
for (int i=9; i>0; i--)
{ arr[i-1]=2*(arr[i]+1); }
为其余各数组元素赋值,则数组元素arr[0]的值便是该问题的解。

2.采用链数据结构实现上述求解 建立单链表,声明一个类用来对链表的结点指针进行定义,在初始化函数中利用头插法创建具有10个元素的链表。

那么N 10便是要求问题的解。

3.采用递归实现上述求解
利用一个递归函数来进行求值:依据返回值来记录每一天剩余桃子情况。

int UseRecursion(int n) {
int m; if(n==1) m=1; else
m=(UseRecursion(n-1)+1)*2; return m; }
五、程序代码
1.头文件“MEP.h “ #ifndef MEP_H #define MEP_H
#include<iostream> #include<malloc.h> using namespace std; typedef struct LNode {
int data;
struct LNode *next; }LNode,*LinkList; void UseLinkList();
int UseRecursion(int n);
int Swicth();
void Diaoyong();
void UseArray();
void Fenxi();
void LinkListAnalysis();
void RecursionAnalysis();
void ArrayAnalysis();
static unsigned short arr[10]={0,0,0,0,0,0,0,0,0,1};
#endif MEP_H;
2.主函数
void Diaoyong();
void main()
{
Diaoyong();
}
3.Diaoyong:调用函数
#include"MEP.h"
void Diaoyong()
{
cout<<" --猴子吃桃子问题-- \n\n";
cout<<"有一群猴子摘了一堆桃子,他们每天都吃当前桃子的一\n";
cout<<"半且再多吃一个,到了第10天就只余下一个桃子。

用多\n";
cout<<"种方法实现求出原来这群猴子共摘了多少个桃子。

\n";
cout<<"要求:\n";
cout<<"(1)采用数组数据结构实现上述求解\n";
cout<<"(2)采用链数据结构实现上述求解\n";
cout<<"(3)采用递归实现上述求解\n";
cout<<"(4)退出程序。

\n";
Swicth();
}
int Swicth()
{
Fenxi();
int n;
for(; ;)
{
cout<<"请输入你要求解的方法:";
cin>>n;
if(n<1 || n>4)
cout<<"输入错误!请重新输入。

";
switch(n)
{
case 1:
ArrayAnalysis();
break;
case 2:
LinkListAnalysis();
break;
case 3:
RecursionAnalysis();
break;
case 4:
return 0;
}
}
}
4.问题分析
#include"MEP.h"
void Fenxi()
{
cout<<"问题分析:\n";
cout<<"猴子每天都吃当前桃子的一半多一个,假设今天还有n\n";
cout<<"个桃子,则前一天就有(n+1)*2个桃子。

又已知第十\n";
cout<<"天只剩下一个桃子,则可代入以上公式求出第九天的\n";
cout<<"桃子数,以此类推求下去便可得到第一天的桃子数。

\n";
cout<<"\n";
}
void ArrayAnalysis()
{
cout<<"数组法是先建一个长度为10的数组,数组第一个元\n";
cout<<"素存储第十天的桃子数为1,然后建立一个for循环\n";
cout<<"语句使a[i+1]=(a[i]+1)*2。

循环执行到a[10]结束\n";
cout<<"。

a[10]中的关键子即为第一天的桃子数。

\n";
cout<<"其结果为:";
UseArray();
cout<<"\n";
}
void LinkListAnalysis()
{
cout<<"链表法采用后序插入的方法,先创建一个空的链表\n";
cout<<"每次生成一个新的节点存储当前桃子数然后插入表\n";
cout<<"头。

最后生成的链表的头结点指向的下一个节点存\n";
cout<<"储的关键字便为第一天的桃子数。

\n";
cout<<"最终结果为:";
UseLinkList();
cout<<"\n";
}
void RecursionAnalysis()
{
cout<<"采用递归的方法求解关键在于写递归函数,函数\n";
cout<<"应定为int型,每次递归上次函数的返回值参与本\n";
cout<<"次的运算。

最后当递归函数返回到第一层最终所得\n";
cout<<"的结果变为第一天的桃子数。

\n";
cout<<"其结果为:";
cout<<UseRecursion(10)<<"\n";
}
5.运用函数求解
#include"MEP.h"
void UseLinkList()
{
LinkList L,p;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
p=(LinkList)malloc(sizeof(LNode));
p->data=1;
p->next=L->next;
L->next=p;
for(int i=1; i<10; i++)
{
p=(LinkList)malloc(sizeof(LNode));
p->data=2*(L->next->data+1);
p->next=L->next;
L->next=p;
}
cout<<L->next->data;
cout<<"\n";
}
int UseRecursion(int n)
{
int m;
if(n==1)
m=1;
else
m=(UseRecursion(n-1)+1)*2;
return m;
}
void UseArray()
{
for (int i=9; i>0; i--)
{
arr[i-1]=2*(arr[i]+1);
}
for(i=0;i<10;i++)
{
cout<<"第<<i+1<<天还剩桃子:"<<arr[i]<<endl; }
}
六、运行结果与测试
七、设计体会与总结
在设计这道程序之前,我本身对数组和递归有了一定的了解,但是对于链结构,我又重新看了一遍算法,对本道题中的猴子吃桃子问题用链结构来解决有了很大的帮助。

在这次的实训中,我对这三个算法,每一个都在出结果前,都做了一下算法分析,然后得出结果。

其中,做好以后,有苦有乐,最主要靠的是自己的恒心与耐心。

通过设计这一道猴子吃桃问题,我觉得只有通过自己不断的钻研,要尽量使自己的不足,用其他方面来弥补了,才能够达到自己想要的预期效果。

对我以后的毕业设计是很有好处的。

《学生搭配问题》报告
一、问题陈述
学生搭配问题
一班有m个女生,有n个男生(m不等于n),现要开一个舞会. 男女生分别编号坐在舞池的两边的椅子上.每曲开始时,依次从男生和女生中各出一人配对跳舞, 本曲没成功配对者坐着等待下一曲找舞伴。

请设计一系统模拟动态地显示出上述过程。

二、需求分析
学生搭配问题
1.输出每曲配对情况
2.计算出任何一个男生(编号为X)和任意女生(编号为Y),在第K曲配对跳舞的情况.至少求出K的两个值。

3.尽量设计出多种算法及程序,可视情况适当加分
三、概要设计
1.class cirularQueue
作用:定义一个一个循环队列
2.~cirularQueue()
作用:定义析构函数,使对象在撤销时释放
3.bool Full()
作用:判断队列是否已满
4.bool Empty()
作用:判断队列是否为空,用于出队列前使用
5.void push(T info)
作用:入队。

每对舞伴跳完舞之后,做入队处理,到达队尾,等待下次跳舞。

6.void Pop(T &info)
作用:出队。

每取曲子响起时男生队列和女生队列作出队处理,两人跳舞。

7.void GetHead(T &info)
作用:取队首元素,对出队的男女进行识别。

四、详细设计
1.循环队列
class cirularQueue //定义一个一个循环队列
{ private:
int MaxSize;
int front; //头指针
int rear; //尾指针
T *data;
public:
cirularQueue(int MaxLength)
{ MaxSize=MaxLength;
front=rear=0;
data=new T[MaxLength];
}
2.析构函数
~cirularQueue() //定义析构函数,使对象在撤销时释放
{ front=rear=0;
delete []data;
}
3.入队
void push(T info) //入队
{ if(IsFull())
{ cout<<"错误!队列已满!"<<endl;
exit(-1);
}
else
{ data[rear]=info;
rear=(rear+1)%MaxSize;
}
}
4.出队
void Pop(T &info) //出队
{ if(IsEmpty())
{ cout<<"错误!队列为空!"<<endl;
exit(-1);
}
else
{ info=data[front];
front=(front+1)%MaxSize;
}
}
5.判断队列是否已满
bool Full() //判断队列是否已满
{ if((rear+1)%MaxSize==front)
return true;
else return false;
}
6.判断队列是否为空
bool Empty() //判断队列是否为空
{ if(front==rear)
return true;
else return false;
}
7.取队首元素
void GetHead(T &info) //取队首元素
{ if(IsEmpty())
{ cout<<"错误!队列为空!"<<endl;
exit (-1);
}
else
{ info=data[front];
}
}
};
五、程序代码
#include<iostream>
template <class T>
class cirularQueue //定义一个一个循环队列{ private:
int MaxSize;
int front; //头指针
int rear; //尾指针
T *data;
public:
cirularQueue(int MaxLength)
{ MaxSize=MaxLength;
front=rear=0;
data=new T[MaxLength];
}
~cirularQueue() //定义析构函数,使对象在撤销时释放{ front=rear=0;
delete []data;
}
void Initqueue() //队列的申明
{ for(int i=0;i<maxSize-1;i++)
push(i);
}
bool Full() //判断队列是否已满
{ if((rear+1)%MaxSize==front)
return true;
else return false;
}
bool Empty() //判断队列是否为空
{ if(front==rear)
return true;
else return false;
}
void push(T info) //入队
{ if(IsFull())
{ cout<<"错误!队列已满!"<<endl;
exit(-1);
}
else
{ data[rear]=info;
rear=(rear+1)%MaxSize;
}
}
void Pop(T &info) //出队
{ if(IsEmpty())
{ cout<<"错误!队列为空!"<<endl;
exit(-1);
}
else
{ info=data[front];
front=(front+1)%MaxSize;
}
}
void GetHead(T &info) //取队首元素
{ if(IsEmpty())
{ cout<<"错误!队列为空!"<<endl;
exit (-1);
}
else
{ info=data[front];
}
}
};
void Initqueue(cirularQueue<int>&,int);
void display(int,int);
void charge(int,int);
using namespace std;
static int songnum=0; //定义歌曲的数量并初始化为0
static int m=0,n=0; //男生和女生的人数
int main() //主函数
{ cout<<"请分别输入男生和女生的人数:";
cin>>m>>n;
display(m,n);
int a=0,b=0; //男生和女生的编号,以判断他们在第几首歌时能在一起跳舞
char quit='y'; //判断是否继续输入,如果继续输入,则输入'y';否则输入'n'
while(quit!='n')
{ cout<<"请输入男生和女生的编号:";
cin>>a>>b;
while((a>m)||(b>n)) //如果输入错误
{ cout<<"输入的编号过大,请重新输入:";
cin>>a>>b;
}
charge(a,b);
cout<<"是否继续(是请输入'y',否则请输入'n'):";
cin>>quit;
}
return 0;
}
void Initqueue(cirularQueue<int> &Q,int m) //初始化队列
{ for(int i=1;i<=m;i++)
Q.push(i);
void display(int m,int n)
{ cirularQueue<int> man(m+1);
cirularQueue<int> woman(n+1);
Initqueue(man,m);
Initqueue(woman,n);
cout<<"请输入曲目数:";
cin>>songnum;
cout<<"每曲的配对情况为:"<<endl;
for(int k=1;k<=songnum;k++)
{ int x=0,y=0; //男生和女生的编号
man.Pop(x); //男生按顺序出对跳舞
woman.Pop(y); //女生按顺序出对跳舞
cout<<"第"<<k<<"曲:\t"<<x<<"号男生<->"<<y<<"号女生"<<endl; //他们在一起跳舞
man.push(x); //跳完舞后男生再次进入队列等在下一次跳舞
woman.push(y); //跳完舞后男生再次进入队列等在下一次跳舞
}
}
void charge(int a,int b)
{ int count=0; //定义舞曲计数以记录他们能在第几曲时在一起跳舞
cirularQueue<int> man1(m+1);
cirularQueue<int> woman1(n+1);
Initqueue(man1,m);
Initqueue(woman1,n);
while(count<=songnum)
{ int x, y;
count++;
man1.Pop(x);
woman1.Pop(y);
man1.push(x);
woman1.push(y);
if((x==a)&&(y==b))
{ cout<<"第"<<count<<"首曲:\t"<<a<<"号男生<->"<<b<<"号女生"<<endl;
break;
}
}
//如果他们在这个舞会上不能在一起跳舞,则输出
if(count==songnum+1)
cout<<"他们在这个舞会上不可能在一起跳舞"<<endl;
}
六、运行结果与测试
七、设计体会与总结
这次的实训,首先碰到这个题目时,我心里不是十分开心,但是,当我构思的时候,还是很难的,所以我自己去查找资料,自己去看书。

最后,这个男女搭配问题,我采用了队列的方式来编程,当入队时,看是否队列为满,当出队时,一定要看队列是否为空。

通过设计这一道男女搭配跳舞问题,我觉得只有通过自己不断的钻研,才能够达到自己想要的预期效果。

只有通过不断地调试,接触、深入实际与亲自动手运用所学的专业知识和技巧,去分析、研究、解决这些问题,从而灵活运用所学知识,增强了实际编程能力,为顺利走向工作岗位打下坚实的基础。

通过对课程设计从分析、设计到实现的全过程剖析和实践,更好地掌握本课程的要领。

相关文档
最新文档