forked from c910335/2D-Rank-Finding-Problem
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cr
More file actions
80 lines (70 loc) · 1.47 KB
/
main.cr
File metadata and controls
80 lines (70 loc) · 1.47 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
THRESHOLD = 23
module Answer
class_property! ranks : Array(Int32)
end
class Point
property! i : Int32, x : Int32, y : Int32
end
def find_ranks(ps : Array(Point), first : Int32, last : Int32)
if last - first <= THRESHOLD
((first + 1)...last).each do |i|
tp = ps[i]
if ps[i].y < ps[first].y
ps[(first + 1)..i] = ps[first...i]
ps[first] = tp
next
end
j = i
loop do
break if ps[i].y >= ps[j - 1].y
j -= 1
end
if j < i
ps[(j + 1)..i] = ps[j...i]
ps[j] = tp
end
Answer.ranks[tp.i] += j - first
end
return
end
mid = (first + last) / 2
find_ranks(ps, first, mid)
find_ranks(ps, mid, last)
tps, i, j, k = ps[first...mid], first, 0, mid
loop do
if tps[j].y <= ps[k].y
ps[i] = tps[j]
j += 1
if j >= tps.size
ps[k...last].each do |p|
Answer.ranks[p.i] += j
end
break
end
else
ps[i] = ps[k]
Answer.ranks[ps[k].i] += j
k += 1
if k >= last
ps[(i + 1)...last] = tps[j..-1]
break
end
end
i += 1
end
end
loop do
n = gets.to_s.chomp.to_i
break if n == 0
ps = Array(Point).new(n) { Point.new }
Answer.ranks = [0] * n
n.times do |i|
ps[i].i, ps[i].x, ps[i].y = [i] + gets.to_s.chomp.split.map(&.to_i)
end
ps.sort! do |a, b|
next a.y <=> b.y if a.x == b.x
a.x <=> b.x
end
find_ranks(ps, 0, n)
puts Answer.ranks.join(' ')
end