main.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package main
  2. import (
  3. "container/heap"
  4. "fmt"
  5. "math"
  6. "sort"
  7. )
  8. // Tuple3 ...
  9. type Tuple3 struct {
  10. _1 int
  11. _2 int
  12. _3 int
  13. }
  14. // Tuple3PQ ...
  15. type Tuple3PQ struct {
  16. queue []Tuple3
  17. length int
  18. }
  19. func (pq Tuple3PQ) Len() int { return pq.length }
  20. func (pq Tuple3PQ) Less(i, j int) bool { return pq.queue[i]._1 < pq.queue[j]._1 }
  21. func (pq Tuple3PQ) Swap(i, j int) { pq.queue[i], pq.queue[j] = pq.queue[j], pq.queue[i] }
  22. // Peek ...
  23. func (pq Tuple3PQ) Peek() Tuple3 { return pq.queue[0] }
  24. // Push ...
  25. func (pq *Tuple3PQ) Push(x interface{}) {
  26. pq.queue = append(pq.queue, x.(Tuple3))
  27. pq.length++
  28. }
  29. // Pop ...
  30. func (pq *Tuple3PQ) Pop() interface{} {
  31. pq.length--
  32. top := pq.queue[pq.length]
  33. pq.queue = pq.queue[:pq.length]
  34. return top
  35. }
  36. func main() {
  37. var T int
  38. fmt.Scan(&T)
  39. for tc := 1; tc <= T; tc++ {
  40. var N, P int
  41. fmt.Scan(&N, &P)
  42. R := make([]int, N)
  43. for i := 0; i < N; i++ {
  44. fmt.Scan(&R[i])
  45. }
  46. Q := make([][]int, N)
  47. for i := 0; i < N; i++ {
  48. Q[i] = make([]int, P)
  49. for j := 0; j < P; j++ {
  50. fmt.Scan(&Q[i][j])
  51. }
  52. sort.Ints(Q[i])
  53. }
  54. lower := make([]float64, N)
  55. for i := 0; i < N; i++ {
  56. lower[i] = float64(9 * R[i]) // Avoid the inaccurate of floating point computation!
  57. }
  58. upper := make([]float64, N)
  59. for i := 0; i < N; i++ {
  60. upper[i] = float64(11 * R[i])
  61. }
  62. var minPQ Tuple3PQ
  63. ptr := make([]int, N)
  64. kits := 0
  65. loop:
  66. for {
  67. maxMin, maxMax := 0, 0
  68. for i := 0; i < N; i++ {
  69. if ptr[i] == P {
  70. break loop
  71. }
  72. gram := float64(Q[i][ptr[i]] * 10)
  73. min := int(math.Ceil(gram / upper[i]))
  74. max := int(math.Floor(gram / lower[i]))
  75. if max == 0 || max < min {
  76. ptr[i]++
  77. i--
  78. continue
  79. }
  80. heap.Push(&minPQ, Tuple3{min, max, i})
  81. maxMin = maxInt(maxMin, min)
  82. maxMax = maxInt(maxMax, max)
  83. }
  84. for minPQ.Peek()._2 < maxMin { // If minMax < maxMin, then no solution for a new kit.
  85. top := heap.Pop(&minPQ).(Tuple3)
  86. moveptr:
  87. ptr[top._3]++
  88. if ptr[top._3] == P {
  89. break loop
  90. }
  91. gram := float64(Q[top._3][ptr[top._3]] * 10)
  92. min := int(math.Ceil(gram / upper[top._3]))
  93. max := int(math.Floor(gram / lower[top._3]))
  94. if max < min {
  95. goto moveptr
  96. }
  97. heap.Push(&minPQ, Tuple3{min, max, top._3})
  98. maxMin = maxInt(maxMin, min)
  99. maxMax = maxInt(maxMax, max)
  100. }
  101. kits++
  102. for minPQ.Len() != 0 {
  103. top := heap.Pop(&minPQ).(Tuple3)
  104. ptr[top._3]++
  105. }
  106. }
  107. fmt.Printf("Case #%d: %d\n", tc, kits)
  108. }
  109. }
  110. func maxInt(x, y int) int {
  111. if x < y {
  112. return y
  113. }
  114. return x
  115. }