PloadyFree

Отбор на Чемпионат юга 2018. Задача E

Mar 20th, 2018
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.37 KB | None | 0 0
  1. package net.egork;
  2.  
  3. import net.egork.io.IOUtils;
  4. import net.egork.utils.io.InputReader;
  5. import net.egork.utils.io.OutputWriter;
  6.  
  7. import java.util.Comparator;
  8. import java.util.List;
  9.  
  10. public class TaskE {
  11.     public void solve(int testNumber, InputReader in, OutputWriter out) {
  12.         time = in.readInt();
  13.         width = in.readInt();
  14.         yRoad = in.readInt();
  15.         carVelocity = in.readInt();
  16.  
  17.         columnStarts = IOUtils.readIntArray(in, columnCount = in.readInt());
  18.         carStarts = IOUtils.readLongArray(in, carCount = in.readInt());
  19.  
  20.         Event[] all = new Event[columnCount * 2 + 2];
  21.         for (int i = 0; i < columnCount; i++) {
  22.             add(all, new Event(columnStarts[i], 0), i * 2);
  23.             add(all, new Event(columnStarts[i] + width, 1), i * 2 + 1);
  24.         }
  25.  
  26.         double answer = 0;
  27.         for (int i = 0; i < carCount; i++) {
  28.             answer += solve(all, carStarts[i]);
  29.         }
  30.         out.printFormat("%.20f", answer);
  31.     }
  32.  
  33.     double solve(Event[] events, long carStart) {
  34.         Event START_EVENT = new Event(getMiddleX(0, carStart), 2);
  35.         Event END_EVENT = new Event(getMiddleX(time, carStart + carVelocity * (double) time), 3);
  36.         if (START_EVENT.pos > END_EVENT.pos) {
  37.             Event t = START_EVENT;
  38.             START_EVENT = END_EVENT;
  39.             END_EVENT = t;
  40.             START_EVENT.type = 2;
  41.             END_EVENT.type = 3;
  42.         }
  43.  
  44.         double len = END_EVENT.pos - START_EVENT.pos;
  45.         double speed = len / time;
  46.  
  47.         if (speed == 0) {
  48.             for (int i = 0; i < columnCount; i++) {
  49.                 if (columnStarts[i] <= START_EVENT.pos && START_EVENT.pos <= columnStarts[i] + width) {
  50.                     return 0;
  51.                 }
  52.             }
  53.             return time;
  54.         }
  55.  
  56.         add(events, START_EVENT, events.length - 2);
  57.         add(events, END_EVENT, events.length - 1);
  58.  
  59.         double answer = 0;
  60.         boolean meStarted = false;
  61.         double lastPos = events[0].pos;
  62.         boolean currentOpened = true;
  63.         for (Event e : events) {
  64.             if (e.type == 2) {
  65.                 meStarted = true;
  66.                 if (currentOpened) {
  67.                     lastPos = e.pos;
  68.                 }
  69.             }
  70.             if (e.type == 3) {
  71.                 if (currentOpened) {
  72.                     answer += (e.pos - lastPos) / speed;
  73.                 }
  74.                 break;
  75.             }
  76.             if (e.type == 0) {
  77.                 currentOpened = false;
  78.                 if (meStarted) {
  79.                     answer += (e.pos - lastPos) / speed;
  80.                 }
  81.             }
  82.             if (e.type == 1) {
  83.                 lastPos = e.pos;
  84.                 currentOpened = true;
  85.             }
  86.         }
  87.  
  88.         remove(events, START_EVENT, events.length);
  89.         remove(events, END_EVENT, events.length - 1);
  90.         return answer;
  91.     }
  92.  
  93.     double getMiddleX(double me, double onRoad) {
  94.         double h = yRoad + 1;
  95.         double delta = (onRoad - me) / h;
  96.         return me + delta;
  97.     }
  98.  
  99.     void add(Event[] a, Event add, int at) {
  100.         a[at] = add;
  101.         while (at > 0 && a[at - 1].compareTo(a[at]) > 0) {
  102.             Event e = a[at - 1];
  103.             a[at - 1] = a[at];
  104.             a[at] = e;
  105.             at--;
  106.         }
  107.     }
  108.  
  109.     void remove(Event[] a, Event rem, int size) {
  110.         for (int i = 0, j = 0; i < size; i++) {
  111.             if (a[i] == rem) continue;
  112.             a[j++] = a[i];
  113.         }
  114.         a[size - 1] = null;
  115.     }
  116.  
  117.     class Event implements Comparable<Event> {
  118.         double pos;
  119.         int type;
  120.         //0 - column start
  121.         //1 - column end
  122.         //2 - my start
  123.         //3 - my end
  124.  
  125.         Event(double pos, int type) {
  126.             this.pos = pos;
  127.             this.type = type;
  128.         }
  129.  
  130.         @Override
  131.         public int compareTo(Event o) {
  132.             int c = Double.compare(pos, o.pos);
  133.             if (c == 0) c = Integer.compare(type, o.type);
  134.             return c;
  135.         }
  136.  
  137.         @Override
  138.         public String toString() {
  139.             return "Event{" +
  140.                     "pos=" + pos +
  141.                     ", type=" + type +
  142.                     '}';
  143.         }
  144.     }
  145.  
  146.     int time;
  147.     int width;
  148.     int yRoad;
  149.     int carVelocity;
  150.  
  151.     int columnCount;
  152.     int[] columnStarts;
  153.  
  154.     int carCount;
  155.     long[] carStarts;
  156. }
Advertisement
Add Comment
Please, Sign In to add comment