main.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package main
  2. import (
  3. "bufio"
  4. "container/list"
  5. "fmt"
  6. "os"
  7. "strconv"
  8. "strings"
  9. )
  10. func leastMalted(scanner *bufio.Scanner) [][]int {
  11. caseCnt := ReadInt(scanner)
  12. answer := make([][]int, caseCnt)
  13. for i := 0; i < caseCnt; i++ {
  14. flavorCnt := ReadInt(scanner)
  15. custCnt := ReadInt(scanner)
  16. custList := list.New()
  17. singleList := list.New()
  18. ansMap := make(map[int]int)
  19. for j := 0; j < custCnt; j++ { // Read all customers => List
  20. custInts := ReadInts(scanner)
  21. cust := list.New()
  22. for k := 1; k < 2*custInts[0]; k += 2 {
  23. cust.PushBack(Pair{custInts[k], custInts[k+1]})
  24. }
  25. if cust.Len() == 1 {
  26. singleList.PushBack(cust)
  27. } else {
  28. custList.PushBack(cust)
  29. }
  30. }
  31. validCase := true
  32. for validCase && singleList.Len() != 0 {
  33. for curr := singleList.Front(); curr != nil; {
  34. cust := curr.Value.(*list.List)
  35. p := cust.Front().Value.(Pair)
  36. if v, ok := ansMap[p._1]; ok && v != p._2 {
  37. // If conflict with ansMap, go to next case
  38. validCase = false
  39. break
  40. }
  41. ansMap[p._1] = p._2 // Else, put into ansMap
  42. next := curr.Next()
  43. singleList.Remove(curr)
  44. curr = next
  45. }
  46. for curr := custList.Front(); validCase && curr != nil; {
  47. cust := curr.Value.(*list.List)
  48. skipCust := false // If customer is already satisfied, skip
  49. for p := cust.Front(); p != nil; {
  50. pair := p.Value.(Pair)
  51. if v, ok := ansMap[pair._1]; ok {
  52. if v != pair._2 {
  53. // Next pair
  54. next := p.Next()
  55. cust.Remove(p)
  56. p = next
  57. continue
  58. }
  59. // Satisfied, skip
  60. skipCust = true
  61. break
  62. }
  63. p = p.Next()
  64. }
  65. if skipCust {
  66. next := curr.Next()
  67. custList.Remove(curr)
  68. curr = next
  69. continue
  70. }
  71. if cust.Len() == 1 { // Move to singleList
  72. singleList.PushBack(cust)
  73. next := curr.Next()
  74. custList.Remove(curr)
  75. curr = next
  76. } else if cust.Len() == 0 { // No candidate, wrong case
  77. validCase = false
  78. } else { // Next cust
  79. curr = curr.Next()
  80. }
  81. }
  82. }
  83. if validCase {
  84. answer[i] = make([]int, flavorCnt)
  85. for k, v := range ansMap {
  86. answer[i][k-1] = v
  87. }
  88. }
  89. }
  90. return answer
  91. }
  92. func main() {
  93. inputFiles := []string{"B-small-practice.in", "B-large-practice.in", "test.in"}
  94. outputFiles := []string{"result-small.out", "result-large.out", "test.out"}
  95. const (
  96. small = iota
  97. large
  98. test
  99. )
  100. fileType := test
  101. fin, _ := os.Open(inputFiles[fileType])
  102. defer fin.Close()
  103. scanner := bufio.NewScanner(fin)
  104. answer := leastMalted(scanner)
  105. fout, _ := os.Create(outputFiles[fileType])
  106. defer fout.Close()
  107. for i, nums := range answer {
  108. var ans string
  109. if len(nums) == 0 {
  110. ans = "IMPOSSIBLE"
  111. } else {
  112. strs := make([]string, len(nums))
  113. for j, n := range nums {
  114. strs[j] = strconv.Itoa(n)
  115. }
  116. ans = strings.Join(strs, " ")
  117. }
  118. s := fmt.Sprintf("Case #%d: %s\n", i+1, ans)
  119. fout.WriteString(s)
  120. }
  121. }