main.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package main
  2. import (
  3. "fmt"
  4. "math"
  5. )
  6. var hd, ad, hk, ak, b, d int
  7. var hp int
  8. type state struct {
  9. hd int
  10. ad int
  11. hk int
  12. ak int
  13. t int
  14. c bool
  15. }
  16. func getBuffCnt() int {
  17. if b == 0 {
  18. return 0
  19. }
  20. bAddA := int(math.Ceil(float64(hk) / float64(ad)))
  21. for cnt := 1; ; cnt++ {
  22. nextBAA := cnt + int(math.Ceil(float64(hk)/float64(ad+cnt*b)))
  23. if bAddA < nextBAA {
  24. return cnt - 1
  25. }
  26. bAddA = nextBAA
  27. }
  28. }
  29. func nextDebuffCnt() int {
  30. if d == 0 || ak == 0 {
  31. return 0
  32. } else if ak <= d {
  33. return 1
  34. }
  35. killed := int(math.Ceil(float64(hd) / float64(ak)))
  36. minAk := int(math.Ceil(float64(hd)/float64(killed))) - 1
  37. return int(math.Ceil(float64(ak-minAk) / float64(d)))
  38. }
  39. func getAttackCnt(st state) int {
  40. if st.ak == 0 {
  41. return maxInt(1, st.hk/st.ad)
  42. }
  43. return maxInt(1, minInt(st.hd/st.ak-1, st.hk/st.ad))
  44. }
  45. func main() {
  46. var T int
  47. fmt.Scan(&T)
  48. for tc := 1; tc <= T; tc++ {
  49. fmt.Scan(&hd, &ad, &hk, &ak, &b, &d)
  50. hp = hd
  51. println("Case", tc)
  52. buff := getBuffCnt()
  53. st := state{hp, ad, hk, ak, 0, false}
  54. for buffCnt := buff; 0 < st.hk; { // !Kill
  55. if st.hd <= st.ak && st.ad < st.hk { // Need cure
  56. if st.c { // Cured?
  57. st.t = 0
  58. break // Die
  59. }
  60. st = state{hd - st.ak, st.ad, st.hk, st.ak, st.t + 1, true} // Cure
  61. continue
  62. }
  63. if buffCnt != 0 {
  64. buffCnt--
  65. st = state{st.hd - st.ak, st.ad + b, st.hk, st.ak, st.t + 1, false} // Buff
  66. continue
  67. }
  68. t := getAttackCnt(st)
  69. st = state{st.hd - st.ak*t, st.ad, st.hk - st.ad*t, st.ak, st.t + t, false} // Attack
  70. }
  71. turn := st.t
  72. debuff, dt := nextDebuffCnt(), 0
  73. sim:
  74. for debuff != 0 {
  75. c := false
  76. for debuff != 0 {
  77. if hp <= ak-d { // Need cure
  78. if c { // Cured?
  79. break sim // Die
  80. }
  81. hp, dt, c = hd-ak, dt+1, true
  82. continue // Cure
  83. }
  84. ak = maxInt(0, ak-d)
  85. debuff, hp, dt, c = debuff-1, hp-ak, dt+1, false // Debuff
  86. } // Simulate debuff
  87. println("sim debuff", dt)
  88. st = state{hp, ad, hk, ak, dt, false}
  89. for buffCnt := buff; 0 < st.hk; { // !Kill
  90. if st.hd <= st.ak && st.ad < st.hk { // Need cure
  91. if st.c { // Cured?
  92. st.t = 0
  93. break // Die
  94. }
  95. st = state{hd - st.ak, st.ad, st.hk, st.ak, st.t + 1, true} // Cure
  96. continue
  97. }
  98. if buffCnt != 0 {
  99. buffCnt--
  100. st = state{st.hd - st.ak, st.ad + b, st.hk, st.ak, st.t + 1, false} // Buff
  101. continue
  102. }
  103. t := getAttackCnt(st)
  104. st = state{st.hd - st.ak*t, st.ad, st.hk - st.ad*t, st.ak, st.t + t, false} // Attack
  105. } // Simulate buff and attack
  106. if turn == 0 || st.t < turn {
  107. turn = st.t
  108. }
  109. debuff = nextDebuffCnt()
  110. }
  111. fmt.Printf("Case #%d: ", tc)
  112. if turn == 0 {
  113. fmt.Println("IMPOSSIBLE")
  114. } else {
  115. fmt.Println(turn)
  116. }
  117. }
  118. }
  119. func maxInt(x, y int) int {
  120. if x < y {
  121. return y
  122. }
  123. return x
  124. }
  125. func minInt(x, y int) int {
  126. if x < y {
  127. return x
  128. }
  129. return y
  130. }