123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- package main
- import (
- "bufio"
- "container/list"
- "fmt"
- "os"
- "strconv"
- "strings"
- )
- func leastMalted(scanner *bufio.Scanner) [][]int {
- caseCnt := ReadInt(scanner)
- answer := make([][]int, caseCnt)
- for i := 0; i < caseCnt; i++ {
- flavorCnt := ReadInt(scanner)
- custCnt := ReadInt(scanner)
- custList := list.New()
- singleList := list.New()
- ansMap := make(map[int]int)
- for j := 0; j < custCnt; j++ { // Read all customers => List
- custInts := ReadInts(scanner)
- cust := list.New()
- for k := 1; k < 2*custInts[0]; k += 2 {
- cust.PushBack(Pair{custInts[k], custInts[k+1]})
- }
- if cust.Len() == 1 {
- singleList.PushBack(cust)
- } else {
- custList.PushBack(cust)
- }
- }
- validCase := true
- for validCase && singleList.Len() != 0 {
- for curr := singleList.Front(); curr != nil; {
- cust := curr.Value.(*list.List)
- p := cust.Front().Value.(Pair)
- if v, ok := ansMap[p._1]; ok && v != p._2 {
- // If conflict with ansMap, go to next case
- validCase = false
- break
- }
- ansMap[p._1] = p._2 // Else, put into ansMap
- next := curr.Next()
- singleList.Remove(curr)
- curr = next
- }
- for curr := custList.Front(); validCase && curr != nil; {
- cust := curr.Value.(*list.List)
- skipCust := false // If customer is already satisfied, skip
- for p := cust.Front(); p != nil; {
- pair := p.Value.(Pair)
- if v, ok := ansMap[pair._1]; ok {
- if v != pair._2 {
- // Next pair
- next := p.Next()
- cust.Remove(p)
- p = next
- continue
- }
- // Satisfied, skip
- skipCust = true
- break
- }
- p = p.Next()
- }
- if skipCust {
- next := curr.Next()
- custList.Remove(curr)
- curr = next
- continue
- }
- if cust.Len() == 1 { // Move to singleList
- singleList.PushBack(cust)
- next := curr.Next()
- custList.Remove(curr)
- curr = next
- } else if cust.Len() == 0 { // No candidate, wrong case
- validCase = false
- } else { // Next cust
- curr = curr.Next()
- }
- }
- }
- if validCase {
- answer[i] = make([]int, flavorCnt)
- for k, v := range ansMap {
- answer[i][k-1] = v
- }
- }
- }
- return answer
- }
- func main() {
- inputFiles := []string{"B-small-practice.in", "B-large-practice.in", "test.in"}
- outputFiles := []string{"result-small.out", "result-large.out", "test.out"}
- const (
- small = iota
- large
- test
- )
- fileType := test
- fin, _ := os.Open(inputFiles[fileType])
- defer fin.Close()
- scanner := bufio.NewScanner(fin)
- answer := leastMalted(scanner)
- fout, _ := os.Create(outputFiles[fileType])
- defer fout.Close()
- for i, nums := range answer {
- var ans string
- if len(nums) == 0 {
- ans = "IMPOSSIBLE"
- } else {
- strs := make([]string, len(nums))
- for j, n := range nums {
- strs[j] = strconv.Itoa(n)
- }
- ans = strings.Join(strs, " ")
- }
- s := fmt.Sprintf("Case #%d: %s\n", i+1, ans)
- fout.WriteString(s)
- }
- }
|