166 lines
4.3 KiB
Java
166 lines
4.3 KiB
Java
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
public class SolutionFlagpoles {
|
|
|
|
public static void main(String[] args) {
|
|
new SolutionFlagpoles().run();
|
|
}
|
|
|
|
int myId = message.MyNodeId();
|
|
int nodeCount = message.NumberOfNodes();
|
|
long itemCount = flagpoles.GetNumFlagpoles();
|
|
|
|
long perNode = itemCount / (nodeCount - 1) + 1;
|
|
long iL = Math.min((myId - 1) * perNode, itemCount);
|
|
long iR = Math.min(myId * perNode, itemCount);
|
|
|
|
void run() {
|
|
if (myId == 0) {
|
|
server();
|
|
} else {
|
|
client();
|
|
}
|
|
}
|
|
|
|
static class Sequence {
|
|
long d;
|
|
long length;
|
|
long startIndex;
|
|
long startElement;
|
|
long endElement;
|
|
|
|
public Sequence(long d, long length, long startIndex, long startElement, long endElement) {
|
|
this.d = d;
|
|
this.length = length;
|
|
this.startIndex = startIndex;
|
|
this.startElement = startElement;
|
|
this.endElement = endElement;
|
|
}
|
|
|
|
static Sequence zero(long startIndex) {
|
|
return new Sequence(0, 0, startIndex, -1, -1);
|
|
}
|
|
|
|
long endIndex() {
|
|
return Math.max(startIndex, startIndex + length - 1);
|
|
}
|
|
|
|
Sequence addElementRight(long element) {
|
|
if (endElement == -1) {
|
|
return new Sequence(0, 1, startIndex, element, element);
|
|
}
|
|
|
|
if (length == 1) {
|
|
return new Sequence(element - startElement, 2, startIndex, startElement, element);
|
|
}
|
|
|
|
if (element - endElement == d) {
|
|
return new Sequence(d, length + 1, startIndex, startElement, element);
|
|
}
|
|
|
|
return new Sequence(element - endElement, 2, startIndex + length - 1, endElement, element);
|
|
}
|
|
|
|
Sequence addSequenceRight(Sequence o) {
|
|
if (endIndex() + 1 != o.startIndex) {
|
|
return o;
|
|
}
|
|
if (o.length == 1) {
|
|
return addElementRight(o.startElement);
|
|
}
|
|
if (d != o.d) {
|
|
if (o.startElement - endElement == o.d) {
|
|
return new Sequence(o.d, o.length + 1, o.startIndex - 1, endElement, o.endElement);
|
|
}
|
|
return o;
|
|
}
|
|
if (o.startElement - endElement != d) {
|
|
return o;
|
|
}
|
|
return new Sequence(d, length + o.length, startIndex, startElement, o.endElement);
|
|
}
|
|
|
|
boolean isBetter(Sequence o) {
|
|
return length > o.length;
|
|
}
|
|
|
|
void send(int target) {
|
|
message.PutLL(target, d);
|
|
message.PutLL(target, length);
|
|
message.PutLL(target, startIndex);
|
|
message.PutLL(target, startElement);
|
|
message.PutLL(target, endElement);
|
|
message.Send(target);
|
|
}
|
|
|
|
static Sequence receive(int source) {
|
|
message.Receive(source);
|
|
return new Sequence(message.GetLL(source), message.GetLL(source), message.GetLL(source), message.GetLL(source), message.GetLL(source));
|
|
}
|
|
|
|
public String toString() {
|
|
return "{" + d + " " + length + " " + startIndex + " " + startElement + " " + endElement + "}";
|
|
}
|
|
}
|
|
|
|
|
|
void client() {
|
|
Map<Long, Long> map = new HashMap<>();
|
|
for (long i = iL; i < iR; i++) {
|
|
map.put(i, flagpoles.GetHeight(i));
|
|
}
|
|
|
|
Sequence best = Sequence.zero(iL);
|
|
Sequence current = Sequence.zero(iL);
|
|
Sequence leftmost = Sequence.zero(iL);
|
|
|
|
for (long i = iL; i < iR; i++) {
|
|
current = current.addElementRight(map.get(i));
|
|
|
|
if (current.startIndex == iL) {
|
|
leftmost = current;
|
|
}
|
|
|
|
if (current.isBetter(best)) {
|
|
best = current;
|
|
}
|
|
}
|
|
|
|
leftmost.send(0);
|
|
current.send(0);
|
|
best.send(0);
|
|
}
|
|
|
|
|
|
void server() {
|
|
Sequence best = Sequence.zero(0);
|
|
Sequence current = Sequence.zero(0);
|
|
|
|
for (int clientId = 1; clientId < nodeCount; clientId++) {
|
|
Sequence clientLeftmost = Sequence.receive(clientId);
|
|
Sequence clientRightmost = Sequence.receive(clientId);
|
|
Sequence clientBest = Sequence.receive(clientId);
|
|
|
|
// System.out.println(clientId + " -> " + clientLeftmost.toString());
|
|
// System.out.println(clientId + " -> " + clientBest.toString());
|
|
|
|
if (clientBest.isBetter(best)) {
|
|
best = clientBest;
|
|
}
|
|
|
|
current = current.addSequenceRight(clientLeftmost);
|
|
// System.out.println(current.toString());
|
|
|
|
if (current.isBetter(best)) {
|
|
best = current;
|
|
}
|
|
|
|
if (clientRightmost.endIndex() > current.endIndex()) {
|
|
current = clientRightmost;
|
|
}
|
|
}
|
|
System.out.println(best.length);
|
|
}
|
|
}
|