-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy path10142.go
116 lines (108 loc) · 2 KB
/
10142.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// UVa 10142 - Australian Voting
package main
import (
"bufio"
"fmt"
"io"
"math"
"os"
"strings"
)
func findLowest(total []int, min int) map[int]bool {
lowest := make(map[int]bool)
for i, v := range total {
if v == min {
lowest[i+1] = true
}
}
return lowest
}
func eliminate(candidates []string, votes [][]int, eliminated map[int]bool) {
for i, vi := range votes {
var newVote []int
for _, vj := range vi {
if !eliminated[vj] {
newVote = append(newVote, vj)
}
}
votes[i] = newVote
}
for i := range candidates {
if eliminated[i+1] {
candidates[i] = ""
}
}
}
func count(out io.Writer, candidates []string, votes [][]int) {
total := make([]int, len(candidates))
for _, v := range votes {
if len(v) > 0 {
total[v[0]-1]++
}
}
max, min := 0, math.MaxInt32
for i, v := range total {
if candidates[i] != "" {
if v > max {
max = v
}
if v < min {
min = v
}
}
}
switch {
case max > len(votes)/2:
for i, v := range total {
if v == max {
fmt.Fprintln(out, candidates[i])
}
}
case max == min:
for _, v := range candidates {
if v != "" {
fmt.Fprintln(out, v)
}
}
default:
lowest := findLowest(total, min)
eliminate(candidates, votes, lowest)
count(out, candidates, votes)
}
}
func main() {
in, _ := os.Open("10142.in")
defer in.Close()
out, _ := os.Create("10142.out")
defer out.Close()
s := bufio.NewScanner(in)
s.Split(bufio.ScanLines)
var kase, n int
s.Scan()
fmt.Sscanf(s.Text(), "%d", &kase)
for s.Scan(); kase > 0 && s.Scan(); kase-- {
fmt.Sscanf(s.Text(), "%d", &n)
candidates := make([]string, n)
for i := range candidates {
s.Scan()
candidates[i] = s.Text()
}
var votes [][]int
var line string
for s.Scan() {
if line = s.Text(); line == "" {
break
}
r := strings.NewReader(line)
vote := make([]int, n)
for i := range vote {
fmt.Fscanf(r, "%d", &vote[i])
}
votes = append(votes, vote)
}
count(out, candidates, votes)
if kase > 1 {
fmt.Fprintln(out)
}
}
}