【实验题】
1.狐狸逮兔子
围绕着山顶有10个圆形排列的洞,狐狸要吃兔子,兔子说:“可以,但必须找到我,我就藏身于这十个洞中,你先到1号洞找,第二次隔1个洞(即3号洞)找,第三次隔2个洞(即6号洞)找,以后如此类推,次数不限。”但狐狸从早到晚进进出出了1000次,仍没有找到兔子。问兔子究竟藏在哪个洞里?
(提示:这实际上是一个反复查找线性表的过程。) 【数据描述】 定义一个顺序表,用具有10个元素顺序表来表示这10个洞。每个元素分别表示围着山顶的一个洞,下标为洞的编号。
#define LIST_INIT_SIZE 10 //线性表存储空间的初始分配量 typedef struct {
ElemType *elem; //存储空间基址 int length; //当前长度
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位) }SqList; 【算法描述】
status InitList_Sq(SqList &L) { //构造一个线性表L
L.elem=(ElemType )malloc(LIST_INIT_SIZE*sizeof(ElemType)); If(!L.elem) return OVERFLOW; //存储分配失败 L.length=0; //空表长度为0 L.listsize=LIST_INIT_SIZE; //初始存储容量 return OK; } //InitList_Sq
status Rabbit(SqList &L) { //构造狐狸逮兔子函数
int current=0; //定义一个当前洞口号的记数器,初始位置为第一个洞口 for(i=0;i L.elem[i]=1; //给每个洞作标记为1,表示狐狸未进之洞 L.elem[LIST_INIT_SIZE-1]=L.elem[0]=0;//首先进入第一个洞,标记进过的洞为0。 for(i=2;i<=1000;i++) { current=(current+i)%LIST_INIT_SIZE;//实现顺序表的循环引用 L.elem[i]=0; // 标记进过的洞为0 }//第二次隔1个洞找,第三次隔2个洞找,以后如此类推,经过一千次 printf(\兔子可能藏在如下的洞中:\ for(i=0;i printf(“ 第%d个洞\\n ”,i+1);//输出未进过的洞号 return OK; }//end 【C源程序】 #include #define OVERFLOW -2 typedef int status; typedef int ElemType; #define LIST_INIT_SIZE 10 /*线性表存储空间的初始分配量 */ typedef struct { ElemType *elem; /* 存储空间基址 */ int length; /* 当前长度 */ int listsize; /*当前分配的存储容量(以sizeof(ElemType)为单位)*/ }SqList; status InitList_Sq(SqList *L){ /*构造一个线性表L */ (*L).elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType)); if(!((*L).elem)) return OVERFLOW; /* 存储分配失败 */ (*L).length=0; /*空表长度为0 */ (*L).listsize=LIST_INIT_SIZE; /*初始存储容量 */ return OK; } /*InitList_Sq */ status Rabbit(SqList *L){ /*构造狐狸逮兔子函数 */ int i,current=0; /*定义一个当前洞口号的记数器,初始位置为第一个洞口*/ for(i=0;i (*L).elem[i]=1; /*给每个洞作标记为1,表示狐狸未进之洞 */ (*L).elem[LIST_INIT_SIZE-1]=0; (*L).elem[0]=0; /*第一次进入第一个洞,标记进过的洞为0 */ for(i=2;i<=1000;i++) { current=(current+i)%LIST_INIT_SIZE;/*实现顺序表的循环引用 */ (*L).elem[current]=0; /* 标记进过的洞为0 */ }/*第二次隔1个洞找,第三次隔2个洞找,以后如此类推,经过一千次 */ printf(\兔子可能藏在如下的洞中:\ for(i=0;i printf(\此洞是第%d号洞 \输出未进过的洞号 */ return OK; } void main() { SqList *L; InitList_Sq(L); Rabbit(L); getch(); } 【测试数据】 最后的输出结果为:2 4 7 9 【说明】 本算法思路比较简单,采用了顺序表表示围着山顶的10个洞,首先对所有洞设置标志为1,然后通过1000次循环,对每次所进之洞修改标志为0,最后输出标志为1的洞。 2.银行客户 某银行有一个客户办理业务站,在单位时间内随机地有客户到达,设每位客户的业务办理时间是某个范围内的随机值。设只有一个窗口,一位业务人员,要求程序模拟统计在设定时间内,业务人员的总空闲时间和客户的平均等待时间。假定模拟数据已按客户到达的先后顺序依次存于某个正文数据文件中。对应每位客户有两个数据,到达时间和需要办理业务的时间。 复习概念: 与栈相对应,队列是一种先进先出的线性表。它只允许在表的一端进行插入,而在另一端进行删除元素。允许插入的一端称队尾,允许删除的一端称队头。插入与删除分别称为入队与出队。队列示意图见图3-2: 出队 ←a1 a2 ?? an-1 ←an进队 队头 队尾 【数据描述】 typedef struct{ int arrive; int treat;//客户的信息结构 }QNODE; typedef struct node{ QNODE data; Struct node *next;//队列中的元素信息 }LNODE LNODE *front,*rear;// 队头指针和队尾指针 【算法描述】 { 设置统计初值; 设置当前时钟时间为0; 打开数据文件,准备读; 读入第一位客户信息于暂存变量中; do{ //约定每轮循环,处理完一位客户 if(等待队列为空,并且还有客户){ //等待队列为空时 累计业务员总等待时间; 时钟推进到暂存变量中的客户的到达时间; 暂存变量中的客户信息进队; 读取下一位客户信息于暂存变量; } 累计客户人数; 从等待队列出队一位客户; 将该客户的等待时间累计到客户的总等待时间; 设定当前客户的业务办理结束时间; while(下一位客户的到达时间在当前客户处理结束之前){ 暂存变量中的客户信息进队; 读取下一位客户信息于暂存变量; } 时钟推进到当前客户办理结束时间; }while(还有未处理的客户); 计算统计结果,并输出; 【C源程序】 #include int treat; /*客户的信息结构*/ }QNODE; typedef struct node{ QNODE data; struct node *next; /*队列中的元素信息*/ }LNODE; LNODE *front,*rear;/* 队头指针和队尾指针*/ QNODE curr,temp; char Fname[120]; FILE *fp; void EnQueue(LNODE **hpt,LNODE **tpt,QNODE e){ /*队列进队*/ LNODE *p=(LNODE *)malloc(sizeof(LNODE)); if(!p) exit(OVERFLOW); /*存储分配失败*/ p->data=e; p->next=NULL; if(*hpt==NULL) *tpt=*hpt=p; else *tpt=(*tpt)->next=p; } int DeQueue(LNODE **hpt,LNODE **tpt,QNODE *cp){ /*链接队列出队*/ LNODE *p=*hpt; if(*hpt==NULL) return 1;/*队空*/ *cp=(*hpt)->data; *hpt=(*hpt)->next; if(*hpt==NULL) *tpt=NULL; free(p); return 0; } void main() { int dwait=0,clock=0,wait=0,count=0,have=0,finish; printf(\ scanf(\输入装客户模拟数据的文件的文件名*/ if((fp=fopen(Fname, \打开数据文件*/ printf(\ return; } front=NULL;rear=NULL; have=fscanf(fp, \ do{ /*约定每轮循环,处理一位客户*/ if(front==NULL && have==2){ /*等待队列为空,但还有客户*/ dwait+=temp.arrive-clock; /*累计业务员总等待时间*/ clock=temp.arrive; /*时钟推进到暂存变量中的客户的到达时间*/ EnQueue(&front,&rear,temp); /* 暂存变量中的客户信息进队*/ have=fscanf(fp, \ } count++; /*累计客户人数*/ DeQueue(&front,&rear,&curr);/*出队一位客户信息*/ wait+=clock-curr.arrive; /*累计到客户的总等待时间*/ finish=clock+curr.treat;/*设定业务办理结束时间;*/
相关推荐: