74.png

    1. /*
    2. 栈和队列应用最后一题:汽车轮渡,要求:每次10辆,客车优先于货车,每上4辆客车才能上1辆货车,客车不足4辆时,货车代替
    3. 货车不足时,允许客车都上
    4. 分析:
    5. 这仍然是一类排序的问题,王道书上的解答可以,核心意思就是客车和货车分为两个队列,客车队列出4辆,紧接着货车
    6. 队列出一辆;当出现客车不足时,出货车队列代替,当货车不足时,继续出客车队列。代码也不难实现,
    7. 这里我想分享一下自己的想法,我们上一题做过货车车厢调整的算法,利用栈将软座调整到硬座的前面,这里我们可以仿造
    8. 相当于我们要将客车调整到货车的前面,只是有限制,每4辆客车就需要插入一辆货车,而面对特殊情况,我们也可以很好
    9. 地处理,直接将剩余车辆(无论客车还是货车)直接连接到队列后面。
    10. 之后我们从队列中取10辆车即可
    11. */
    12. #include <stdio.h>
    13. struct Stack {
    14. int *arr;
    15. int len;
    16. int top;
    17. };
    18. void manageCar(int *arrCar, int *arrArrange, Stack *s) {
    19. int i = 0, passengerCar = 0, j = 0;
    20. int *c;//接收出栈硬座
    21. bool push(Stack *, int);
    22. int *top(Stack *);
    23. bool pop(Stack *);
    24. bool empty(Stack *);
    25. for (; arrCar[i] == 1 || arrCar[i] == 2; i++) {
    26. if (arrCar[i] == 2 && passengerCar < 4) {//如果是货车且之前还没有4辆客车,入栈
    27. push(s, arrCar[i]);
    28. }
    29. else {//若是客车,直接入arrArrange
    30. if (passengerCar == 4) {//若之前已有连续4辆客车,出栈入货车
    31. if (!empty(s)) {
    32. c = top(s);
    33. pop(s);
    34. arrArrange[j++] = *c;
    35. passengerCar = 0;//重新计数
    36. }
    37. }
    38. arrArrange[j++] = arrCar[i];
    39. passengerCar++;//连续客车数加一
    40. }
    41. }
    42. while (!empty(s)) {//栈内元素不空,加入到arrArrange
    43. c = top(s);
    44. pop(s);
    45. arrArrange[j++] = *c;
    46. }
    47. }
    48. int main() {
    49. int arrCar[] = { 2,1,2,1,1,1,1,2,2,2,1,1 };//我们用1代表客车,用2发表货车,arrCar代表当前的车序列,然后我们需要重排
    50. int arrArrange[20] = { 0 };//初始化为0,接收重排的车队
    51. Stack *createStack(int);
    52. Stack *s;
    53. s = createStack(20);//创建一个栈
    54. manageCar(arrCar, arrArrange, s);
    55. for (int i = 0; i < 10; i++) {//取10辆车出来
    56. printf("%d ", *(arrArrange + i));
    57. }
    58. return 0;
    59. }