数据结构:球钟问题

问题描述∶

球钟是一个利用球的移动来记录时间的简单装置。它有三个可以容纳若干个球的指示器∶分钟指
示器,五分钟指示器,小时指示器。若分钟指示器中有2个球,五分钟指示器中有6个球,小时指示器中有5个球,则时间为5:32


工作原理∶

 

每过一分钟,球钟就会从球队列的队首取出一个球放入分钟指示器,分钟指示器最多可容纳4个
球。当放入第五个球时,在分钟指示器的4个球就会按照他们被放入时的相反顺序加入球队列的队尾。而第五个球就会进入五分钟指示器。按此类推,五分钟指示器最多可放11个球,小时指示器最多可放11个球。当小时指示器放入第12个球时,原来的11个球按照他们被放入时的相反顺序加入球队列的队尾,然后第12个球也回到队尾。这时,三个指示器均为空,回到初始状态,从而形成一个循环。因此,该球钟表示时间的范围是从0∶0O到11 :59。
现设初始时球队列的球数为27,球钟的三个指示器初态均为空。问,要经过多久,球队列才能回复到原来的顺序?

思路解决

栈和队列的应用,主要使用顺序栈(有大小)和链式队列(操作方便)。假定时间为队列,里面存了1-27的数字。队列不为空时从队列中取数。分钟,5分钟,1小时为三个栈,min栈容量为4,5min栈容量为11,hour栈容量为11。从中取出的数先进入分钟栈,不满则入栈,满了则讲分钟栈的元素出栈后入队。5min,hour栈同理。如果hour栈满入队,需要讲最后一个元素放入入队。

完成队列顺序的检查,两个元素比较,如果没有两个则不比较。如果顺序正确返回1。

源代码

 https://blog.csdn.net/qq_64532606/article/details/132283829?spm=1001.2014.3001.5502
https://blog.csdn.net/qq_64532606/article/details/132284088?spm=1001.2014.3001.5502

上文链接栈和队列代码,下文为球钟问题代码

/*===============================================
 *   文件名称:main.c
 *   创 建 者:     
 *   创建日期:2023年08月14日
 *   描    述:
 ================================================*/
#include "linkqueue.h"
#include "sqstack.h"

int check(linkqueue*lq){
    if(lq==NULL){
        printf("null\n");
        return -1;
    }

    linklist p = lq->front->next;
    while(p&&p->next){
        if((p->data)<(p->next->data)){
            p=p->next;
        }
        else{
            return 0;
        }
    }

    return 1;
}
int main(int argc, char *argv[])
{ 

    int min=0;
    linkqueue* lq=queue_create();  
    if(lq==NULL){
        return -1;
    }

    sqstack* s_hour,*s_5min,*s_min;
    if((s_hour=stack_create(11))==NULL){
        return -1;
    }
    if((s_5min=stack_create(11))==NULL){
        return -1;
    }
    if((s_min=stack_create(4))==NULL){
        return -1;
    }


    for(int i=1;i<=27;i++){
        enqueue(lq,i);
    }


    int value;
    while(1){
        min++;
        if(queue_empty(lq)!=0){
            value=dequeue(lq);

            if(stack_full(s_min)!=1){
                stack_push(s_min,value);
            }else{
                while(stack_empty(s_min)!=1){
                    enqueue(lq,stack_pop(s_min));
                }
                if(stack_full(s_5min)!=1){
                    stack_push(s_5min,value);
                }else{
                    while(stack_empty(s_5min)!=1){
                        enqueue(lq,stack_pop(s_5min));
                    }

                    if(stack_full(s_hour)!=1){
                        stack_push(s_hour,value);
                    }else{
                        while(stack_empty(s_hour)!=1){
                            enqueue(lq,stack_pop(s_hour));
                        }
                        enqueue(lq,value);
                        //0:0
                        if(check(lq) == 1)
                        {
                            break;
                        }
                    }



                }  


            }


        }
    }

    printf("total:%d",min);
    puts("");
    while(queue_empty(lq)!=0){
        printf("%d  ",dequeue(lq));
    }

    return 0;
} 

运行结果图

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值