Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package net.egork;
- import net.egork.io.IOUtils;
- import net.egork.utils.io.InputReader;
- import net.egork.utils.io.OutputWriter;
- import java.util.Comparator;
- import java.util.List;
- public class TaskE {
- public void solve(int testNumber, InputReader in, OutputWriter out) {
- time = in.readInt();
- width = in.readInt();
- yRoad = in.readInt();
- carVelocity = in.readInt();
- columnStarts = IOUtils.readIntArray(in, columnCount = in.readInt());
- carStarts = IOUtils.readLongArray(in, carCount = in.readInt());
- Event[] all = new Event[columnCount * 2 + 2];
- for (int i = 0; i < columnCount; i++) {
- add(all, new Event(columnStarts[i], 0), i * 2);
- add(all, new Event(columnStarts[i] + width, 1), i * 2 + 1);
- }
- double answer = 0;
- for (int i = 0; i < carCount; i++) {
- answer += solve(all, carStarts[i]);
- }
- out.printFormat("%.20f", answer);
- }
- double solve(Event[] events, long carStart) {
- Event START_EVENT = new Event(getMiddleX(0, carStart), 2);
- Event END_EVENT = new Event(getMiddleX(time, carStart + carVelocity * (double) time), 3);
- if (START_EVENT.pos > END_EVENT.pos) {
- Event t = START_EVENT;
- START_EVENT = END_EVENT;
- END_EVENT = t;
- START_EVENT.type = 2;
- END_EVENT.type = 3;
- }
- double len = END_EVENT.pos - START_EVENT.pos;
- double speed = len / time;
- if (speed == 0) {
- for (int i = 0; i < columnCount; i++) {
- if (columnStarts[i] <= START_EVENT.pos && START_EVENT.pos <= columnStarts[i] + width) {
- return 0;
- }
- }
- return time;
- }
- add(events, START_EVENT, events.length - 2);
- add(events, END_EVENT, events.length - 1);
- double answer = 0;
- boolean meStarted = false;
- double lastPos = events[0].pos;
- boolean currentOpened = true;
- for (Event e : events) {
- if (e.type == 2) {
- meStarted = true;
- if (currentOpened) {
- lastPos = e.pos;
- }
- }
- if (e.type == 3) {
- if (currentOpened) {
- answer += (e.pos - lastPos) / speed;
- }
- break;
- }
- if (e.type == 0) {
- currentOpened = false;
- if (meStarted) {
- answer += (e.pos - lastPos) / speed;
- }
- }
- if (e.type == 1) {
- lastPos = e.pos;
- currentOpened = true;
- }
- }
- remove(events, START_EVENT, events.length);
- remove(events, END_EVENT, events.length - 1);
- return answer;
- }
- double getMiddleX(double me, double onRoad) {
- double h = yRoad + 1;
- double delta = (onRoad - me) / h;
- return me + delta;
- }
- void add(Event[] a, Event add, int at) {
- a[at] = add;
- while (at > 0 && a[at - 1].compareTo(a[at]) > 0) {
- Event e = a[at - 1];
- a[at - 1] = a[at];
- a[at] = e;
- at--;
- }
- }
- void remove(Event[] a, Event rem, int size) {
- for (int i = 0, j = 0; i < size; i++) {
- if (a[i] == rem) continue;
- a[j++] = a[i];
- }
- a[size - 1] = null;
- }
- class Event implements Comparable<Event> {
- double pos;
- int type;
- //0 - column start
- //1 - column end
- //2 - my start
- //3 - my end
- Event(double pos, int type) {
- this.pos = pos;
- this.type = type;
- }
- @Override
- public int compareTo(Event o) {
- int c = Double.compare(pos, o.pos);
- if (c == 0) c = Integer.compare(type, o.type);
- return c;
- }
- @Override
- public String toString() {
- return "Event{" +
- "pos=" + pos +
- ", type=" + type +
- '}';
- }
- }
- int time;
- int width;
- int yRoad;
- int carVelocity;
- int columnCount;
- int[] columnStarts;
- int carCount;
- long[] carStarts;
- }
Advertisement
Add Comment
Please, Sign In to add comment