球钟问题的解决--栈和队列

球钟问题描述:球钟是一个利用球的移动来记录时间的简单装置。它有三个可以容纳若干个球的指示器:分钟指示器,五分钟指示器,小时指示器。若分钟指示器中有2个球,5分钟指示器中有6个球,小时指示器中有5个球,则时间为5:32。
    
工作原理:每过一分钟,球钟就会从球队列的队首取出一个球放入分钟指示器,分钟指示器最多可容纳4个球。当放入第五个球时,在分钟指示器的4个球就会按照他们被放入时的相反顺序加入球队列的队尾。而第五个球就会进入分钟指示器。按此类推,五分钟指示器最多可放11个球,小时指示器最多可放11个球。当小时指示器放入第12个球时,原来的11个球按照他们被放入时的相反顺序加入球队列的队尾,然后第12个球也回到队尾。这时,三个指示器均为空,回到初始状态,从而形成一个循环。因此,该秋种表示的时间范围是从00:00到11:59
 
请看示意图(图是从网上找的,不好勿喷啊!!):
 
思考:
    要想表示00:00到12:00需要多少个球?假设,指示器都为空,球队列需要多长时间能回到原来的状态?
答案是总共组要27个球,当每个指示器满的时候,为了保证队列不为空,所以为4+11+11+1=27。下面解决第二个问题:
 
这里我为了管理方便,采用了make工程管理器,总共有以下几个文件:
main.c  queue.c  stack.c  queue.h  stack.h  Makefile
这里的main文件不用说,肯定就是主函数,而stack.c和queue.c是分别定义栈和队列操作的函数,而两个头文件是定义这些函数的接口。
搞清楚了文件之间的关系后,请看源码:
queue.c文件:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-family:SimSun;font-size:12px;">/************************************************************************* 
  2.     > File Name: queue.c 
  3.     > Author: Baniel Gao  
  4.     > Mail: createchance@163.com  
  5.     > Blog: blog.csdn.net/createchance  
  6.     > Created Time: 2013年12月21日 星期六 11时13分10秒 
  7.  ************************************************************************/  
  8. #include "queue.h"  
  9.   
  10. linkqueue_st *linkqueue_init(int size)  
  11. {  
  12.     linkqueue_st *queue = NULL;  
  13.   
  14.     queue = (linkqueue_st *)malloc(sizeof(linkqueue_st));  
  15.     queue->total = size;  
  16.     queue->current = 0;  
  17.     queue->head = linkqueue_node_create(0);  
  18.     queue->tail = queue->head;  
  19.   
  20.     return queue;  
  21. }  
  22.   
  23. nodequeue_st *linkqueue_node_create(int value)  
  24. {  
  25.     nodequeue_st *node = NULL;  
  26.   
  27.     node = (nodequeue_st *)malloc(sizeof(nodequeue_st));  
  28.     node->data = value;  
  29.     node->next = NULL;  
  30.   
  31.     return node;  
  32. }  
  33.   
  34. int linkqueue_enqueue(linkqueue_st *queue, int value)  
  35. {  
  36.     nodequeue_st *new = NULL;  
  37.   
  38.     if(linkqueue_isfull(queue))  
  39.         return -1;  
  40.     new = linkqueue_node_create(value);  
  41.     queue->tail->next = new;  
  42.     queue->tail = new;  
  43.     queue->current++;  
  44.   
  45.     return 0;  
  46. }  
  47.   
  48. int linkqueue_dequeue(linkqueue_st *queue, int *value)  
  49. {  
  50.     nodequeue_st *tmp;  
  51.   
  52.     if(linkqueue_isempty(queue))  
  53.         return -1;  
  54.     tmp = queue->head;  
  55.     *value = tmp->next->data;  
  56.     queue->head = tmp->next;  
  57.     free(tmp);  
  58.     queue->current--;  
  59.   
  60.     return 0;  
  61. }  
  62.   
  63. int linkqueue_isfull(linkqueue_st *queue)  
  64. {  
  65.     if(queue->current == queue->total)  
  66.         return 1;  
  67.     return 0;  
  68. }  
  69.   
  70. int linkqueue_isempty(linkqueue_st *queue)  
  71. {  
  72.     if(queue->current == 0)  
  73.         return 1;  
  74.     return 0;  
  75. }  
  76.   
  77. int linkqueue_free(linkqueue_st *queue)  
  78. {  
  79.     nodequeue_st *p = queue->head;  
  80.     nodequeue_st *tmp;  
  81.   
  82.     while(p != NULL) {  
  83.         tmp = p;  
  84.         p = p->next;  
  85.         free(tmp);  
  86.     }  
  87.     free(queue);  
  88.   
  89.     return 0;  
  90. }</span>  

这里的栈是使用的链式存储实现的,具体的思想请看本人的前几个帖子。
stack.c:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-family:SimSun;font-size:12px;">/************************************************************************* 
  2.     > File Name: stack.c 
  3.     > Author: Baniel Gao  
  4.     > Mail: createchance@163.com  
  5.     > Blog: blog.csdn.net/createchance  
  6.     > Created Time: 2013年12月21日 星期六 11时13分18秒 
  7.  ************************************************************************/  
  8. #include "stack.h"  
  9.   
  10. seqstack_st *seqstack_init(int size)  
  11. {  
  12.     seqstack_st *stack = NULL;  
  13.   
  14.     stack = (seqstack_st *)malloc(sizeof(seqstack_st));  
  15.     stack->total = size;  
  16.     stack->top = 0;  
  17.     stack->data = (int *)malloc(sizeof(int) * size);  
  18.   
  19.     return stack;  
  20. }  
  21.   
  22. int seqstack_push(seqstack_st *stack, int value)  
  23. {  
  24.     if(seqstack_isfull(stack))  
  25.         return -1;  
  26.     stack->data[stack->top++] = value;  
  27.   
  28.     return 0;  
  29. }  
  30.   
  31. int seqstack_pop(seqstack_st *stack, int *value)  
  32. {  
  33.     if(seqstack_isempty(stack))  
  34.         return -1;  
  35.     *value = stack->data[--stack->top];  
  36.   
  37.     return 0;  
  38. }  
  39.   
  40. int seqstack_isfull(seqstack_st *stack)  
  41. {  
  42.     if(stack->top == stack->total)  
  43.         return 1;  
  44.     return 0;  
  45. }  
  46.   
  47. int seqstack_isempty(seqstack_st *stack)  
  48. {  
  49.     if(stack->top == 0)  
  50.         return 1;  
  51.     return 0;  
  52. }  
  53.   
  54. int seqstack_free(seqstack_st *stack)  
  55. {  
  56.     free(stack->data);  
  57.     free(stack);  
  58.   
  59.     return 0;  
  60. }</span>  

这里的栈实现是使用的连续存储实现的,具体的思想比较简单,就不多说了。
两个头文件:
queue.h:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-family:SimSun;font-size:12px;">/************************************************************************* 
  2.     > File Name: queue.h 
  3.     > Author: Baniel Gao  
  4.     > Mail: createchance@163.com  
  5.     > Blog: blog.csdn.net/createchance  
  6.     > Created Time: 2013年12月21日 星期六 12时01分54秒 
  7.  ************************************************************************/  
  8. #ifndef _QUEUE_H_  
  9. #define _QUEUE_H_  
  10.   
  11. #include <stdio.h>  
  12. #include <stdlib.h>  
  13.   
  14. typedef struct _nodequeue_ {  
  15.     int data;  
  16.     struct _nodequeue_ *next;  
  17. } nodequeue_st;  
  18.   
  19. typedef struct _linkqueue_ {  
  20.     int total;  
  21.     int current;  
  22.     nodequeue_st *head;  
  23.     nodequeue_st *tail;  
  24. } linkqueue_st;  
  25.   
  26. linkqueue_st *linkqueue_init(int size);  
  27. nodequeue_st *linkqueue_node_create(int value);  
  28. int linkqueue_enqueue(linkqueue_st *queue, int value);  
  29. int linkqueue_isfull(linkqueue_st *queue);  
  30. int linkqueue_dequeue(linkqueue_st *queue, int *value);  
  31. int linkqueue_isempty(linkqueue_st *queue);  
  32. int linkqueue_free(linkqueue_st *queue);  
  33.   
  34. #endif</span>  

stack.h:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-family:SimSun;font-size:12px;">/************************************************************************* 
  2.     > File Name: stack.h 
  3.     > Author: Baniel Gao  
  4.     > Mail: createchance@163.com  
  5.     > Blog: blog.csdn.net/createchance  
  6.     > Created Time: 2013年12月21日 星期六 11时58分18秒 
  7. ************************************************************************/  
  8. #ifndef _STACK_H_  
  9. #define _STACK_H_  
  10.   
  11. #include <stdio.h>  
  12. #include <stdlib.h>  
  13.   
  14. typedef struct _seqstack_ {  
  15.     int total;  
  16.     int top;  
  17.     int *data;  
  18. } seqstack_st;  
  19.   
  20. seqstack_st *seqstack_init(int size);  
  21. int seqstack_push(seqstack_st *stack, int value);  
  22. int seqstack_isfull(seqstack_st *stack);  
  23. int seqstack_pop(seqstack_st *stack, int *value);  
  24. int seqstack_isempty(seqstack_st *stack);  
  25. int seqstack_free(seqstack_st *stack);  
  26.   
  27. #endif</span>  

下面请看最关键的主函数的实现:
main.c:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-family:SimSun;font-size:12px;">/************************************************************************* 
  2.     > File Name: main.c 
  3.     > Author: Baniel Gao  
  4.     > Mail: createchance@163.com  
  5.     > Blog: blog.csdn.net/createchance  
  6.     > Created Time: 2013年12月21日 星期六 11时13分24秒 
  7.  ************************************************************************/  
  8. #include "queue.h"  
  9. #include "stack.h"  
  10.   
  11. int queue_check(linkqueue_st *queue);  
  12. void debug(linkqueue_st *queue);  
  13.   
  14. int main(void)  
  15. {  
  16.     int timer = 0;  
  17.     int value = 1;  
  18.     int tmp;  
  19.     int queue_size = 27;  
  20.     int stack_m1_size = 4;  
  21.     int stack_m5_size = 11;  
  22.     int stack_h1_size = 11;  
  23.     linkqueue_st *queue;  
  24.     seqstack_st *stack_m1;  
  25.     seqstack_st *stack_m5;  
  26.     seqstack_st *stack_h1;  
  27.       
  28.     queue = linkqueue_init(queue_size);  
  29.     stack_m1 = seqstack_init(stack_m1_size);  
  30.     stack_m5 = seqstack_init(stack_m5_size);  
  31.     stack_h1 = seqstack_init(stack_h1_size);  
  32.     while(-1 != linkqueue_enqueue(queue, value))  
  33.         value++;  
  34.     while(1) {  
  35.         linkqueue_dequeue(queue, &value);  
  36.         if(-1 != seqstack_push(stack_m1, value))  
  37.             continue;  
  38.       
  39.         while(-1 != seqstack_pop(stack_m1, &tmp))  
  40.             linkqueue_enqueue(queue, tmp);  
  41.       
  42.         if(-1 != seqstack_push(stack_m5, value))  
  43.             continue;  
  44.   
  45.         while(-1 != seqstack_pop(stack_m5, &tmp))  
  46.             linkqueue_enqueue(queue, tmp);  
  47.   
  48.         if(-1 != seqstack_push(stack_h1, value))  
  49.             continue;  
  50.   
  51.         while(-1 != seqstack_pop(stack_h1, &tmp))  
  52.             linkqueue_enqueue(queue, tmp);  
  53.   
  54.         linkqueue_enqueue(queue, value);  
  55.         timer++;  
  56.         debug(queue);  
  57.         if(queue_check(queue))  
  58.             break;  
  59.     }  
  60.     printf("The time is %d hours!\n", timer*12);  
  61.   
  62.   
  63.     linkqueue_free(queue);  
  64.     seqstack_free(stack_m1);  
  65.     seqstack_free(stack_m5);  
  66.     seqstack_free(stack_h1);  
  67.   
  68.     return 0;  
  69. }  
  70. void debug(linkqueue_st *queue)  
  71. {  
  72.     nodequeue_st *p = queue->head->next;  
  73.   
  74.     while(p != NULL) {  
  75.         printf("%d  ", p->data);  
  76.         p = p->next;  
  77.     }  
  78.     putchar('\n');  
  79. }  
  80.   
  81. int queue_check(linkqueue_st *queue)  
  82. {  
  83.     nodequeue_st *p = queue->head->next;  
  84.   
  85.     while(p != NULL && p->next != NULL) {  
  86.         if(p->data > p->next->data)  
  87.             return 0;  
  88.         p = p->next;  
  89.     }  
  90.   
  91.     return 1;  
  92. }</span>  

其中的debug函数是为了方便调试而设置的,并且可以用它来打印每隔12个小时的队列情况
下面是Makefile:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-family:SimSun;font-size:12px;">CC:= gcc  
  2. CFLAGS:= -Wall -O2 -c  
  3. OBJ:= ballclock  
  4.   
  5. .PHONY: clean memcheck  
  6.   
  7. $(OBJ): main.o stack.o queue.o  
  8.     $(CC) -o $@ $^  
  9. main.o: main.c stack.h queue.h  
  10.     $(CC) -o $@ $< $(CFLAGS)  
  11. queue.o: queue.c queue.h  
  12.     $(CC) -o $@ $< $(CFLAGS)  
  13. stack.o: stack.c stack.h  
  14.     $(CC) -o $@ $< $(CFLAGS)  
  15.   
  16. clean:  
  17.     rm -rf *.o $(OBJ)  
  18.   
  19. memcheck:  
  20.     valgrind --tool=memcheck ./$(OBJ)</span>  

这个问题看似很难,其实用计算机程序来实现的话是不难的,只要找到基本规律,然后用循环让计算机不停地去做就可以了。
运行结果是552个小时,也就是23天!!

原文出处:http://blog.csdn.net/createchance/article/details/17466053
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
骑士游历问题是指在一个给定的棋盘上,骑士从任意一个方格出发,只能按照“日”字型的步伐进行移动,直到覆盖棋盘上的每一个方格,求出骑士的移动路径。 这个问题可以使用深度优先搜索(DFS)和广度优先搜索(BFS)算法来解决。而栈和队列则可以用来实现DFS和BFS算法。 下面是使用java栈和队列解决骑士游历问题的代码示例: ```java import java.util.*; public class KnightTour { private static int[][] board; private static int[] dx = {-2, -1, 1, 2, 2, 1, -1, -2}; private static int[] dy = {1, 2, 2, 1, -1, -2, -2, -1}; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("请输入棋盘大小:"); int n = scanner.nextInt(); board = new int[n][n]; System.out.print("请输入起始位置x坐标:"); int startX = scanner.nextInt(); System.out.print("请输入起始位置y坐标:"); int startY = scanner.nextInt(); System.out.println("BFS算法求解:"); bfs(startX, startY, n); System.out.println(); System.out.println("DFS算法求解:"); dfs(startX, startY, n); System.out.println(); } // BFS算法 private static void bfs(int x, int y, int n) { Queue<int[]> queue = new LinkedList<>(); queue.offer(new int[]{x, y}); board[x][y] = 1; while (!queue.isEmpty()) { int[] cur = queue.poll(); int cx = cur[0], cy = cur[1]; System.out.println("(" + cx + "," + cy + ")"); for (int i = 0; i < 8; i++) { int nx = cx + dx[i], ny = cy + dy[i]; if (nx >= 0 && nx < n && ny >= 0 && ny < n && board[nx][ny] == 0) { queue.offer(new int[]{nx, ny}); board[nx][ny] = board[cx][cy] + 1; } } } } // DFS算法 private static void dfs(int x, int y, int n) { Stack<int[]> stack = new Stack<>(); stack.push(new int[]{x, y}); board[x][y] = 1; while (!stack.isEmpty()) { int[] cur = stack.pop(); int cx = cur[0], cy = cur[1]; System.out.println("(" + cx + "," + cy + ")"); for (int i = 0; i < 8; i++) { int nx = cx + dx[i], ny = cy + dy[i]; if (nx >= 0 && nx < n && ny >= 0 && ny < n && board[nx][ny] == 0) { stack.push(new int[]{nx, ny}); board[nx][ny] = board[cx][cy] + 1; } } } } } ``` 在上面的代码中,我们定义了一个`board`二维数组来表示棋盘,其中0表示未走过的格子,1表示起始位置,2表示第二步,以此类推。`dx`和`dy`数组分别表示骑士的8种移动方式。`bfs`方法和`dfs`方法分别使用队列和来实现BFS和DFS算法。使用`System.out.println`打印出每一个移动的位置,最终可以得到骑士的移动路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值