解法一:队列+模拟

用N个队列模拟银行窗口的队列,每次找出排在第一位且完成时间最早、窗口编号最小的顾客办理业务,并更然后加入一位未进入队列的顾客,更新队首顾客的完成时间。
需要注意的一个坑:如果一个顾客开始办理业务的时间早于17:00,完成时间晚于17:00,那么银行也需要为他办理业务。

  1. import java.io.*;
  2. import java.util.*;
  3. public class Main {
  4. public static void main(String[] args) throws IOException {
  5. StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
  6. PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
  7. in.nextToken();
  8. int N = (int) in.nval;
  9. in.nextToken();
  10. int M = (int) in.nval;
  11. in.nextToken();
  12. int K = (int) in.nval;
  13. in.nextToken();
  14. int Q = (int) in.nval;
  15. Customer[] customers = new Customer[K];
  16. for (int i = 0; i < K; ++i) {
  17. in.nextToken();
  18. customers[i] = new Customer((int) in.nval);
  19. }
  20. List<Queue<Customer>> windows = new ArrayList<>();
  21. for (int i = 0; i < N; ++i) {
  22. windows.add(new LinkedList<>());
  23. }
  24. int toAdd;
  25. for (toAdd = 0; (toAdd < K) && (toAdd < N * M); ++toAdd) {
  26. windows.get(toAdd % N).offer(customers[toAdd]);
  27. }
  28. int todo = 0;
  29. while (todo < K) {
  30. int min = 0x3f3f3f3f;
  31. Customer next = null;
  32. int windowID = -1;
  33. for (int i = 0; i < windows.size(); ++i) {
  34. Customer customer = windows.get(i).peek();
  35. if (customer == null) {
  36. continue;
  37. }
  38. // 完成时间最短, 窗口编号小的优先
  39. if ((customer.time - customer.cost < 540) && (customer.time < min)) {
  40. min = customer.time;
  41. next = customer;
  42. windowID = i;
  43. }
  44. }
  45. // 没有需要服务的客户
  46. if (next == null) {
  47. break;
  48. }
  49. // 更新自己和队列中下一个人的状态
  50. next.isFinish = true;
  51. Queue<Customer> queue = windows.get(windowID);
  52. queue.poll();
  53. if (toAdd < K) {
  54. queue.offer(customers[toAdd++]);
  55. }
  56. if (!queue.isEmpty()) {
  57. queue.peek().time += next.time;
  58. }
  59. ++todo;
  60. }
  61. for (int i = 0; i < Q; ++i) {
  62. in.nextToken();
  63. int index = (int) in.nval - 1;
  64. out.println(customers[index]);
  65. }
  66. out.flush();
  67. }
  68. }
  69. class Customer {
  70. // 处理时间
  71. int cost;
  72. // 完成时间
  73. int time;
  74. // 是否能被银行处理
  75. boolean isFinish;
  76. public Customer(int cost) {
  77. this.cost = cost;
  78. time = cost;
  79. isFinish = false;
  80. }
  81. @Override
  82. public String toString() {
  83. if (isFinish) {
  84. int minute = (time + 480) / 60;
  85. int second = time % 60;
  86. return String.format("%02d:%02d", minute, second);
  87. }
  88. return "Sorry";
  89. }
  90. }