技巧
并查集
思路
齐齐和司机分别开一个并查集
合并会级联影响到的大炮
rankMap维护当前集合中的个数
若要消灭掉司机 需要齐齐 len(sijiRanlMap) - 1 次 操作 (齐齐现出手 所以要-1)
然后升序排列一下齐齐的rankmap 算个差值就好
实现
package main
import (
"bufio"
. "fmt"
"io"
"os"
"sort"
"strings"
)
type E struct {
x, y int
}
type UnionSet struct {
eMap map[E]bool
faterMap map[E]E
rankMap map[E]int
}
func NewUnionSet() *UnionSet {
return &UnionSet{
make(map[E]bool),
make(map[E]E),
make(map[E]int),
}
}
func (us *UnionSet) getHead(e E) E {
if us.faterMap[e] == e {
return e
}
head := us.getHead(us.faterMap[e])
us.faterMap[e] = head
return head
}
func (us *UnionSet) isSame(var1, var2 E) bool {
return us.getHead(var1) == us.getHead(var2)
}
func (us *UnionSet) union(var1, var2 E) {
if us.isSame(var1, var2) {
return
}
fvar1, fvar2 := us.faterMap[var1], us.faterMap[var2]
if us.rankMap[fvar1] >= us.rankMap[fvar2] {
us.faterMap[fvar2] = fvar1
us.rankMap[fvar1] += us.rankMap[fvar2]
delete(us.rankMap, fvar2)
} else {
us.faterMap[fvar1] = fvar2
us.rankMap[fvar2] += us.rankMap[fvar1]
delete(us.rankMap, fvar1)
}
}
// 8方向
var d = [8][2]int{{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {-1, -1}, {1, 1}, {-1, 1}, {1, -1}}
func merge(uset *UnionSet) {
for key, _ := range uset.eMap {
for i := 0; i < 8; i++ {
if _, ok := uset.eMap[E{key.x + d[i][0], key.y + d[i][1]}]; ok {
uset.union(key, E{key.x + d[i][0], key.y + d[i][1]})
}
}
}
}
func NC14698(_r io.Reader, _w io.Writer) {
in, out := bufio.NewReader(_r), bufio.NewWriter(_w)
defer out.Flush()
var m int
Fscan(in, &m)
SiJi := [4][]string{}
sijiUset := NewUnionSet()
for i := 0; i < 4; i++ {
var line string
Fscan(in, &line)
SiJi[i] = strings.Split(line, "")
for j := 0; j < m; j++ {
if SiJi[i][j] == "*" {
e := E{i, j}
sijiUset.eMap[e] = true
sijiUset.faterMap[e] = e
sijiUset.rankMap[e] = 1
}
}
}
QiQi := [4][]string{}
qiqiUset := NewUnionSet()
for i := 0; i < 4; i++ {
var line string
Fscan(in, &line)
QiQi[i] = strings.Split(line, "")
for j := 0; j < m; j++ {
if QiQi[i][j] == "*" {
e := E{i, j}
qiqiUset.eMap[e] = true
qiqiUset.faterMap[e] = e
qiqiUset.rankMap[e] = 1
}
}
}
merge(sijiUset)
merge(qiqiUset)
if len(qiqiUset.rankMap) < len(sijiUset.rankMap) {
Fprintln(out, -1)
} else {
a := make([]int, len(qiqiUset.rankMap))
k := 0
total := 0
for _, v := range qiqiUset.rankMap {
a[k] = v
total += v
k++
}
sort.Ints(a)
tmp := 0
for i := 0; i < len(sijiUset.rankMap)-1; i++ {
tmp += a[i]
}
Fprintln(out, total-tmp)
}
}
func main() {
NC14698(os.Stdin, os.Stdout)
}

京公网安备 11010502036488号