-
Notifications
You must be signed in to change notification settings - Fork 0
/
Flat.java
152 lines (136 loc) · 4.24 KB
/
Flat.java
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
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;
class Range implements Comparable<Range>
{
public void setval(Range prt, int nb, int bgn, int ed)
{
parent = prt;
number = nb;
begin = bgn;
end = ed;
rank = (parent == null)? 1: parent.rank + 1;
}
@Override
public int compareTo(Range o){
return this.begin - o.begin;
}
Range parent;
int number;
int begin;
int end;
int rank;
};
class Ranges
{
// set ranges will store
public TreeSet<Range> range_set = new TreeSet<>();
// toFind is used to find the new node within range_set
private Range toFind = new Range();
// Find the range which contains given number or return null.
public Range find(int number)
{
toFind.begin = number; // note: set begin with number to search
if(range_set.size() < 1) return null;
Range result = (number < range_set.first().begin)? range_set.first(): range_set.floor(toFind);
// because range_set's size >=1, so "I" couldn't equal to range_set.end()
return (result.begin <= number && result.end > number)? result: null;
}
// Add range to range_set
void add(Range new_range)
{
/* traverse all the nodes untill *I's begin >=range->end */
Iterator<Range> iterator = range_set.iterator();
while(iterator.hasNext())
{
Range x = iterator.next();
if(x.begin >= new_range.end) break;
// find the first overlapping range
if (x.end <= new_range.begin)
{
continue;
}
/*
* if new_range's rank is higher, to get the longest sequence,
* replace current range with new_range's
*/
if(new_range.rank > x.rank)
{
/*
* new_range: |------|
* current range: |-----|
*/
if(new_range.begin > x.begin)
x.end = new_range.begin;
/*
* new_range: |------|
* current range: |-----|
*/
else if(new_range.end < x.end)
x.begin = new_range.end;
/*
* new_range: |------|
* current range: |---|
*/
else {
iterator.remove();
continue;
}
} else {
/*
* the new range doesn't has higher rank, according to
* requirement, x's range will be used for later
* coming ranges
*/
if(new_range.begin < x.begin || new_range.end <= x.end)
new_range.end = x.begin;
else
new_range.begin = x.end;
}
} //end of while
range_set.add(new_range);
} //end of add()
};
public class Flat{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int number;
int n = scan.nextInt();
int k = scan.nextInt();
Ranges ranges = new Ranges();
Range max = null;
Range range, parent;
if (n >= 1)
{
number = scan.nextInt();
range = new Range();
parent = null;
range.setval(parent, number, number - k, number + k + 1);
max = range;
ranges.add(range);
}
for (int i=1; i<n; i++) {
number = scan.nextInt();
parent = ranges.find(number);
range = new Range();
range.setval(parent, number, number - k, number + k + 1);
if (max.rank < range.rank) {
max = range;
}
ranges.add(range);
}
int[] result = new int[max.rank];
int rank = max.rank;
int i = rank - 1;
while (max != null) {
result[i] = max.number;
max = max.parent;
i--;
}
i = 0;
while (i < rank) {
System.out.println(result[i]);
i++;
}
}
}