-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path087.swift
More file actions
178 lines (151 loc) · 2.97 KB
/
087.swift
File metadata and controls
178 lines (151 loc) · 2.97 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
func readIntArray() -> [Int] {
readLine()!.split(separator: " ").map { Int(String($0))! }
}
let npk = readIntArray()
let n = npk[0]
let p = npk[1]
let k = npk[2]
var a: [[Int]] = []
for _ in 0..<n {
a.append(readIntArray())
}
var undef: [(Int, Int)] = []
for i in 0..<n {
for j in 0..<n {
if a[i][j] == -1 {
undef.append((i, j))
}
}
}
func inP(x: Int) -> Int {
for u in undef {
a[u.0][u.1] = x
}
var counter = 0
for i in 0..<n {
var order: [(c: Int, s: Int)] = []
for j in 0..<n {
if i != j {
order.append((c: j, s: a[i][j]))
}
}
order = order.sorted(by: { $0.s < $1.s })
let orderCount = order.count
var current = 0
while current < orderCount - 1 { //最後は除く
let target = order[current].c
for k in current + 1..<orderCount {
let checked = order[k].c
if order[current].s + a[target][checked] < order[k].s {
order[k].s = order[current].s + a[target][checked]
var movingLeft = k
while order[movingLeft].s < order[movingLeft - 1].s {
let temp = order[movingLeft]
order[movingLeft] = order[movingLeft - 1]
order[movingLeft - 1] = temp
movingLeft -= 1
}
}
}
current += 1
}
for o in order {
if o.s <= p {
counter += 1
}
}
}
return counter / 2
}
/*
xを上げると結果は同じか下がるので
inP(x: 1)とinP(x: p + 1)の結果は
1: k未満
p+1: k未満
1: k
p+1: k未満
1: k
p+1: k
1: kより大
p+1: k未満
1: kより大
p+1: k
1: kより大
p+1: kより大
の6つ
*/
let oneResult = inP(x: 1)
let pPlusOneResult = inP(x: p + 1)
if oneResult < k || pPlusOneResult > k {
print(0)
} else if pPlusOneResult == k {
print("Infinity")
} else {
//oneResult >= k かつ pPlusOneResult < k
var underK = 0 //Kより下となるxの下端
var overK = 0 //Kより上となるxの上端
//最終的にoverK < underKである
do {
var l = 1
var r = p + 1
var mid = 0
while r - l >= 2 {
mid = (l + r) / 2
let midResult = inP(x: mid)
if midResult >= k {
l = mid
} else if midResult < k {
r = mid
}
}
underK = r
}
if oneResult > k {
var l = 1
var r = underK
var mid = 0
while r - l >= 2 {
mid = (l + r) / 2
let midResult = inP(x: mid)
if midResult > k {
l = mid
} else if midResult <= k {
r = mid
}
}
overK = l
}
print(underK - overK - 1)
}
/*
上であげた6パターンを
kを徐々に変えてデバッグする方法
斜め
6 5 k
0 -1 10 4 6 2
-1 0 14 3 -1 15
10 14 0 2 -1 -1
4 3 2 0 5 7
6 -1 -1 5 0 22
2 15 -1 7 22 0
k = 16 -> 0 (1: k未満、p+1: k未満)
k = 15 -> 2 (1: k、p+1: k未満)
k = 14 -> 0 (1: k超え、p+1: k未満)
k = 13 -> 1
k = 12 -> 0
k = 11 -> 0
k = 10 -> 2
k = 9 -> 0
k = 8 -> 0
k = 7 -> 0 (1: k超え、p+1: k未満)
k = 6 -> Infinity (1: k超え、p+1: k)
k = 5 -> 0 (1: k超え、p+1: k超え)
水平
3 8 k
0 1 10
1 0 3
10 3 0
k = 4 -> 0 (1: k未満、p+1: k未満)
k = 3 -> Infinity (1: k、p+1: k)
k = 2 -> 0 (1: k超え、p+1: k超え)
*/