GCJ2011 Qualification Round B "Magicka"

問題:https://code.google.com/codejam/contest/dashboard?c=975485#s=p1

Google Code Jam nise..nabeで参加.

エレメントの融合条件,エレメントの相反条件,素材エレメントが与えられる.素材エレメントの頭からエレメントリストに以下のように追加していく.

  1. 融合条件に該当するエレメントが連続して出現したときは融合結果になってエレメントリストに追加される.
  2. 融合条件に該当しなかった場合,かつ,エレメントリストに含まれるエレメントが相反条件に当てはまったときはエレメントリストをクリアする.
  3. 融合条件および相反条件にあてはまらなかった場合はそのエレメントをエレメントリストに追加する.

以上の手順を踏んだ結果のエレメントリストの中身を求める.

単純にシミュレート.

コード

package main

import (
	"os"
	"bufio"
	"container/vector"
	"fmt"
	"io"
	"io/ioutil"
	"strconv"
	"strings"
)

func run() {
	for t, T := 1, s.next(); t <= T; t++ {
		c := s.next()
		combs := make([][]string, c)
		for i := range combs {
			combs[i] = strings.Split(s.nextStr(), "", -1)
		}
		d := s.next()
		opps := make([][]string, d)
		for i := range opps {
			opps[i] = strings.Split(s.nextStr(), "", -1)
		}
		s.next()
		elems := s.nextStr()
		list := new(vector.StringVector)
	l:
		for _, v := range strings.Split(elems, "", -1) {
			if list.Len() > 0 {
				for _, comb := range combs {
					if comb[0] == v || comb[1] == v {
						u := ""
						if comb[0] == v {
							u = comb[1]
						} else {
							u = comb[0]
						}
						if u == list.Last() {
							list.Pop()
							list.Push(comb[2])
							continue l
						}
					}
				}
				for _, opp := range opps {
					if opp[0] == v || opp[1] == v {
						u := ""
						if opp[0] == v {
							u = opp[1]
						} else {
							u = opp[0]
						}
						for i := 0; i < list.Len(); i++ {
							if u == list.At(i) {
								list = new(vector.StringVector)
								continue l
							}
						}
					}
				}
			}
			list.Push(v)
		}
		result := make([]string, list.Len())
		for i := range result {
			result[i] = list.At(i)
		}
		s.println("Case #", t, ": ", "[", strings.Join(result, ", "), "]")
	}

}

func main() {
	s = NewInOut(os.Stdin, os.Stdout)
	run()
	s.Flush()
}

var (
	s *InOut
)

// io start

type InOut struct {
	in []byte
	*bufio.Writer
}

func NewInOut(r io.Reader, w io.Writer) *InOut {
	in, _ := ioutil.ReadAll(r)
	return &InOut{in, bufio.NewWriter(w)}
}

func (s *InOut) next() (r int) {
	buf := s.in
	p := 1
	for (buf[0] < '0' || '9' < buf[0]) && buf[0] != '-' {
		buf = buf[1:]
	}
	if buf[0] == '-' {
		p = -1
		buf = buf[1:]
	}
	for '0' <= buf[0] && buf[0] <= '9' {
		r = 10*r + int(buf[0]-'0')
		buf = buf[1:]
	}
	r *= p
	s.in = buf
	return
}

func (s *InOut) nextStr() (r string) {
	buf := s.in
	for buf[0] == '\n' || buf[0] == ' ' {
		buf = buf[1:]
	}
	p := 0
	for buf[p] != '\n' && buf[p] != ' ' {
		p++
	}
	r = string(buf[0:p])
	s.in = buf[p:]
	return
}

func (s *InOut) print(os ...interface{}) {
	for _, o := range os {
		switch i := o.(type) {
		case byte:
			s.WriteByte(o.(byte))
		case string:
			s.WriteString(o.(string))
		case int:
			s.WriteString(strconv.Itoa(o.(int)))
		case int64:
			s.WriteString(strconv.Itoa64(o.(int64)))
		default:
			s.WriteString(fmt.Sprint(o))
		}
	}
}

func (s *InOut) println(os ...interface{}) {
	for _, o := range os {
		s.print(o)
	}
	s.print("\n")
}

func (s *InOut) printlnNow(os ...interface{}) {
	for _, o := range os {
		fmt.Println(o)
	}
}

// io end