-
-
Notifications
You must be signed in to change notification settings - Fork 24
/
task.go
131 lines (109 loc) · 2.63 KB
/
task.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package main
import (
"bufio"
"fmt"
"io"
"os"
"strconv"
"strings"
)
// CompetitionResult структура элемента
type CompetitionResult struct {
name string
complete int
fail int
}
// Queue структура очереди
type Queue struct {
queue []CompetitionResult
lastIndex int
}
func main() {
res := strings.Builder{}
PyramidSort(os.Stdin, &res)
fmt.Println(res.String())
}
// PyramidSort основная функция на вход
func PyramidSort(r io.Reader, w *strings.Builder) {
scanner := bufio.NewScanner(r)
scanner.Scan()
n, _ := strconv.Atoi(scanner.Text())
pq := Queue{queue: make([]CompetitionResult, n+1), lastIndex: 0}
for i := 0; i < n; i++ {
scanner.Scan()
fields := strings.Fields(scanner.Text())
name := fields[0]
complete, _ := strconv.Atoi(fields[1])
fail, _ := strconv.Atoi(fields[2])
pq.Append(CompetitionResult{name, complete, fail})
}
for i := 0; i < n; i++ {
w.WriteString(pq.Next().name)
w.WriteByte('\n')
}
}
// Append добавление элемента в очередь
func (pq *Queue) Append(cr CompetitionResult) {
pq.lastIndex++
pq.queue[pq.lastIndex] = cr
pq.UpSifting(pq.lastIndex)
}
// Next получение приоритетного элемента из кучи
func (pq *Queue) Next() CompetitionResult {
defer func() {
pq.queue[1] = pq.queue[pq.lastIndex]
pq.queue = pq.queue[:pq.lastIndex]
pq.DownSifting(1)
pq.lastIndex--
}()
return pq.queue[1]
}
// UpSifting просеивания вверх
func (pq Queue) UpSifting(index int) {
if index == 1 {
return
}
parentIndex := index >> 1
if pq.Less(index, parentIndex) {
pq.Swap(index, parentIndex)
pq.UpSifting(parentIndex)
}
}
// DownSifting просеивания вниз
func (pq Queue) DownSifting(index int) {
left := index * 2
right := index*2 + 1
if left >= pq.Len() {
return
}
best := 0
if right < pq.Len() && pq.Less(right, left) {
best = right
} else {
best = left
}
if pq.Less(best, index) {
pq.Swap(best, index)
pq.DownSifting(best)
}
}
// Less проверка приоритета
func (pq Queue) Less(a, b int) bool {
if pq.queue[a].complete == pq.queue[b].complete {
if pq.queue[a].fail == pq.queue[b].fail {
return pq.queue[a].name < pq.queue[b].name
} else {
return pq.queue[a].fail <= pq.queue[b].fail
}
} else {
return pq.queue[a].complete >= pq.queue[b].complete
}
}
// Swap классическая функция смены
func (pq Queue) Swap(a, b int) {
pq.queue[a], pq.queue[b] = pq.queue[b], pq.queue[a]
}
// Len текущий размер очереди
func (pq Queue) Len() int {
return len(pq.queue)
}