Advertisement
Gassa

checker for problem "transfer"

Mar 14th, 2016
508
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 24.13 KB | None | 0 0
  1. // Author: Ivan Kazmenko (gassa@mail.ru)
  2. #include "testlib.h"
  3. #include <algorithm>
  4. #include <cassert>
  5. #include <cmath>
  6. #include <cstdio>
  7. #include <cstdlib>
  8. #include <ctime>
  9. #include <set>
  10. #include <stdint.h>
  11. #include <vector>
  12.  
  13. using namespace std;
  14.  
  15. struct LCG // for portability: 48-bit random numbers engine used in Java
  16. {
  17.     static const int64_t LCG_MULT = 0x5DEECE66DLL;
  18.     static const int64_t LCG_ADD  =         0xBLL;
  19.     static const int64_t LCG_MASK = (1LL << 48) - 1;
  20.  
  21.     int64_t state;
  22.  
  23.     void init (int64_t seed)
  24.     {
  25.         state = (seed ^ LCG_MULT) & LCG_MASK;
  26.     }
  27.  
  28.     int next ()
  29.     {
  30.         state = ((state * LCG_MULT) + LCG_ADD) & LCG_MASK;
  31.         return (int) (state >> 17);
  32.     }
  33.  
  34.     int uniform (int range) // [0..range)
  35.     {
  36.         if (range <= 0)
  37.         {
  38.             assert (false);
  39.         }
  40.         if ((range & -range) == range)
  41.         {
  42.             return (int) ((range * 1LL * next ()) >> 31);
  43.         }
  44.         int limit = (0x7FFFFFFF / range) * range;
  45.         int temp;
  46.         do
  47.         {
  48.             temp = next ();
  49.         }
  50.         while (temp >= limit);
  51.         return temp % range;
  52.     }
  53.  
  54.     int uniform (int lo, int hi) // [lo..hi]
  55.     {
  56.         return lo + uniform (hi - lo + 1);
  57.     }
  58. };
  59.  
  60. struct Time
  61. {
  62.     int value;
  63.  
  64.     Time ()
  65.     {
  66.     }
  67.  
  68.     Time (int newValue)
  69.     {
  70.         value = newValue;
  71.     }
  72.  
  73.     Time (const Time & other)
  74.     {
  75.         value = other.value;
  76.     }
  77.  
  78.     Time operator + (const Time other) const
  79.     {
  80.         return Time (value + other.value);
  81.     }
  82.  
  83.     Time operator - (const Time other) const
  84.     {
  85.         return Time (value - other.value);
  86.     }
  87.  
  88.     Time & operator += (const Time other)
  89.     {
  90.         value += other.value;
  91.         return *this;
  92.     }
  93. };
  94.  
  95. bool operator < (const Time a, const Time b)
  96. {
  97.     return a.value < b.value;
  98. }
  99.  
  100. bool operator > (const Time a, const Time b)
  101. {
  102.     return a.value > b.value;
  103. }
  104.  
  105. bool operator != (const Time a, const Time b)
  106. {
  107.     return a.value != b.value;
  108. }
  109.  
  110. Time seconds (int value)
  111. {
  112.     return Time (value);
  113. }
  114.  
  115. Time minutes (int value)
  116. {
  117.     return Time (value * 60);
  118. }
  119.  
  120. Time hours (int value)
  121. {
  122.     return Time (value * 60 * 60);
  123. }
  124.  
  125. struct Point
  126. {
  127.     int x;
  128.     int y;
  129.  
  130.     Point ()
  131.     {
  132.     }
  133.  
  134.     Point (int newX, int newY)
  135.     {
  136.         x = newX;
  137.         y = newY;
  138.     }
  139. };
  140.  
  141. bool operator < (const Point a, const Point b)
  142. {
  143.     if (a.x != b.x)
  144.     {
  145.         return a.x < b.x;
  146.     }
  147.     return a.y < b.y;
  148. }
  149.  
  150. int64_t distSquared (const Point & p, const Point & q)
  151. {
  152.     return (q.x - p.x) * 1LL * (q.x - p.x) +
  153.         (q.y - p.y) * 1LL * (q.y - p.y);
  154. }
  155.  
  156. struct Query
  157. {
  158.     int from;
  159.     int to;
  160.     Time moment;
  161.  
  162.     Query ()
  163.     {
  164.     }
  165.  
  166.     Query (int newFrom, int newTo, Time newMoment)
  167.     {
  168.         from = newFrom;
  169.         to = newTo;
  170.         moment = newMoment;
  171.     }
  172. };
  173.  
  174. struct Driver
  175. {
  176.     int garage;
  177.     Time momentStart;
  178.     Time momentFinish;
  179.  
  180.     Driver ()
  181.     {
  182.     }
  183.  
  184.     Driver (int newGarage, Time newMomentStart, Time newMomentFinish)
  185.     {
  186.         garage = newGarage;
  187.         momentStart = newMomentStart;
  188.         momentFinish = newMomentFinish;
  189.     }
  190. };
  191.  
  192. enum COMMAND {NO_COMMAND, MOVE, PICK1, PICK2, DROP1, DROP2};
  193.  
  194. struct Instruction
  195. {
  196.     COMMAND command;
  197.     Time moment;
  198.     int arg1;
  199.     int arg2;
  200. };
  201.  
  202. struct Solution
  203. {
  204.     vector <vector <Instruction> > instruction;
  205.  
  206.     void read (InStream & stream)
  207.     {
  208.         instruction.clear ();
  209.         while (!stream.seekEof ())
  210.         {
  211.             int curDriver = (int) instruction.size ();
  212.             vector <Instruction> cur;
  213.             string temp = stream.readLine ();
  214.  
  215.             stringstream noLine;
  216.             noLine << "driver ";
  217.             noLine << curDriver;
  218.             noLine << ": no";
  219.             if (temp == noLine.str ())
  220.             {
  221.                 instruction.push_back (cur);
  222.                 continue;
  223.             }
  224.  
  225.             stringstream yesLine;
  226.             yesLine << "driver ";
  227.             yesLine << curDriver;
  228.             yesLine << ": yes";
  229.             if (temp != yesLine.str ())
  230.             {
  231.                 quitf (_pe, "expected `%s' or `%s', "
  232.                     "found `%s'", yesLine.str ().c_str (),
  233.                     noLine.str ().c_str (), temp.c_str ());
  234.             }
  235.  
  236.             while (true)
  237.             {
  238.                 int curLine = (int) cur.size () + 1;
  239.                 string line = stream.readLine ();
  240.                 if (line == "end")
  241.                 {
  242.                     break;
  243.                 }
  244.                 stringstream buf (line);
  245.                 string command;
  246.                 buf >> command;
  247.                 int args = -1;
  248.                 Instruction instr;
  249.                 if (command == "move")
  250.                 {
  251.                     instr.command = MOVE;
  252.                     args = 1;
  253.                 }
  254.                 else if (command == "pick1")
  255.                 {
  256.                     instr.command = PICK1;
  257.                     args = 1;
  258.                 }
  259.                 else if (command == "pick2")
  260.                 {
  261.                     instr.command = PICK2;
  262.                     args = 2;
  263.                 }
  264.                 else if (command == "drop1")
  265.                 {
  266.                     instr.command = DROP1;
  267.                     args = 1;
  268.                 }
  269.                 else if (command == "drop2")
  270.                 {
  271.                     instr.command = DROP2;
  272.                     args = 2;
  273.                 }
  274.                 else
  275.                 {
  276.                     quitf (_pe, "driver %d, command %d: "
  277.                         "expected command or `end', "
  278.                         "found `%s'", curDriver, curLine,
  279.                         command.c_str ());
  280.                 }
  281.                 buf >> instr.moment.value;
  282.                 if (args >= 1)
  283.                 {
  284.                     buf >> instr.arg1;
  285.                 }
  286.                 if (args >= 2)
  287.                 {
  288.                     buf >> instr.arg2;
  289.                 }
  290.                 string temp;
  291.                 buf >> temp;
  292.                 if (temp != "")
  293.                 {
  294.                     quitf (_pe, "driver %d, command %d: "
  295.                         "got `%s' after arguments",
  296.                         curDriver, curLine,
  297.                         temp.c_str ());
  298.                 }
  299.                 cur.push_back (instr);
  300.             }
  301.             instruction.push_back (cur);
  302.         }
  303.     }
  304. };
  305.  
  306. struct SolutionResult
  307. {
  308.     int64_t expenses;
  309.     int queriesMissed;
  310.     int q;
  311.     int driversHired;
  312.     int d;
  313.  
  314.     SolutionResult (int64_t newExpenses, int newQueriesMissed, int newQ,
  315.         int newDriversHired, int newD)
  316.     {
  317.         expenses = newExpenses;
  318.         queriesMissed = newQueriesMissed;
  319.         q = newQ;
  320.         driversHired = newDriversHired;
  321.         d = newD;
  322.     }
  323. };
  324.  
  325. struct Test
  326. {
  327.     static const Point origin;
  328.  
  329.     LCG rnd;
  330.     unsigned seed;
  331.     int r, a, g, q, n, dm, d;
  332.  
  333.     vector <Point> point;
  334.     vector <Query> query;
  335.     vector <Driver> driver;
  336.     vector <vector <int> > gdist;
  337.     vector <vector <Time> > gtime;
  338.  
  339.     Point uniformFreePoint (set <Point> & visited, int r)
  340.     {
  341.         Point res;
  342.         do
  343.         {
  344.             res.x = rnd.uniform (-r, +r);
  345.             res.y = rnd.uniform (-r, +r);
  346.         }
  347.         while (distSquared (origin, res) > r * 1LL * r ||
  348.             visited.find (res) != visited.end ());
  349.         return res;
  350.     }
  351.  
  352.     void addFarPoints (set <Point> & visited, int num)
  353.     {
  354.         int startPos = point.size ();
  355.         for (int i = 0; i < num; i++)
  356.         {
  357.             vector <Point> temp;
  358.             vector <int64_t> minDistSquared;
  359.             int64_t maxDistSquared = -1;
  360.             for (int j = 0; j <= i; j++)
  361.             {
  362.                 Point curPoint = uniformFreePoint (visited, r);
  363.                 int64_t curDistSquared = r * 9LL * r;
  364.                 for (int k = 0; k < i; k++)
  365.                 {
  366.                     curDistSquared = min (curDistSquared,
  367.                         distSquared (point[startPos + k],
  368.                         curPoint));
  369.                 }
  370.                 maxDistSquared = max (maxDistSquared,
  371.                     curDistSquared);
  372.                 temp.push_back (curPoint);
  373.                 minDistSquared.push_back (curDistSquared);
  374.             }
  375.  
  376.             int j = 0;
  377.             while (maxDistSquared != minDistSquared[j])
  378.             {
  379.                 j++;
  380.                 if (j > i)
  381.                 {
  382.                     assert (false);
  383.                 }
  384.             }
  385.             point.push_back (temp[j]);
  386.             visited.insert (temp[j]);
  387.         }
  388.     }
  389.  
  390.     Point skewFreePoint (set <Point> & visited, int r)
  391.     {
  392.         Point res;
  393.         do
  394.         {
  395.             Point pre;
  396.             do
  397.             {
  398.                 pre.x = rnd.uniform (-r, +r);
  399.                 pre.y = rnd.uniform (-r, +r);
  400.             }
  401.             while (distSquared (origin, pre) > r * 1LL * r);
  402.  
  403.             static const int p = 1000003;
  404.             int s = rnd.uniform (1, p);
  405.             res = Point ((int)
  406.                 (round (pre.x * 1.0 * s / p)), (int)
  407.                 (round (pre.y * 1.0 * s / p)));
  408.         }
  409.         while (visited.find (res) != visited.end ());
  410.         return res;
  411.     }
  412.  
  413.     void generatePoints ()
  414.     {
  415.         point.clear ();
  416.         point.reserve (n);
  417.         set <Point> visited;
  418.  
  419.         addFarPoints (visited, a);
  420.  
  421.         addFarPoints (visited, g);
  422.  
  423.         for (int i = 0; i < q; i++)
  424.         {
  425.             Point curPoint = skewFreePoint (visited, r);
  426.             point.push_back (curPoint);
  427.             visited.insert (curPoint);
  428.         }
  429.     }
  430.  
  431.     void generateQueries ()
  432.     {
  433.         query.clear ();
  434.         query.reserve (q);
  435.         set <Time> times [a];
  436.         int curNumber = a + g;
  437.         while ((int) query.size () < q)
  438.         {
  439.             int t = rnd.uniform (0, 1);
  440.             int atemp = rnd.uniform (1, a);
  441.             int b = rnd.uniform (0, atemp - 1);
  442.             Time m;
  443.             do
  444.             {
  445.                 m = minutes (rnd.uniform (3 * 60, 21 * 60));
  446.             }
  447.             while (times[b].find (m) != times[b].end ());
  448.             times[b].insert (m);
  449.             int w = rnd.uniform (1, 20);
  450.             int c;
  451.             do
  452.             {
  453.                 c = rnd.uniform (1, w);
  454.             }
  455.             while ((int) query.size () + c > q);
  456.             for (int i = 0; i < c; i++)
  457.             {
  458.                 query.push_back (Query
  459.                     ((t == 0) ? curNumber : b,
  460.                     (t == 0) ? b : curNumber, m));
  461.                 curNumber++;
  462.             }
  463.         }
  464.     }
  465.  
  466.     void generateDrivers ()
  467.     {
  468.         driver.clear ();
  469.         driver.reserve (d);
  470.         for (int i = 0; i < d; i++)
  471.         {
  472.             int gtemp = rnd.uniform (1, g);
  473.             int h = rnd.uniform (0, gtemp - 1);
  474.             Time m = hours (rnd.uniform (0, 12));
  475.             driver.push_back (Driver (h + a, m, m + hours (12)));
  476.         }
  477.     }
  478.  
  479.     void generateMatrices ()
  480.     {
  481.         gdist = vector <vector <int> > (n, vector <int> (n));
  482.         gtime = vector <vector <Time> > (n, vector <Time> (n));
  483.         for (int u = 0; u < n; u++)
  484.         {
  485.             for (int v = 0; v < n; v++)
  486.             {
  487.                 int e = (int) (ceil (sqrt (distSquared
  488.                     (point[u], point[v]) * 1.0)));
  489.                 int t = (int) (ceil (e * 60.0 / 1000));
  490.                 gdist[u][v] = rnd.uniform (e, 2 * e);
  491.                 gtime[u][v] = seconds (rnd.uniform (t, 2 * t));
  492.             }
  493.         }
  494.     }
  495.  
  496.     void generate (unsigned newSeed)
  497.     {
  498.         seed = newSeed;
  499.         rnd.init (seed);
  500.  
  501.         r = rnd.uniform (10000, 50000);
  502.  
  503.         do
  504.         {
  505.             a = rnd.uniform (1, 5);
  506.             g = rnd.uniform (1, 10);
  507.             q = rnd.uniform (500, 2000);
  508.             n = a + g + q;
  509.         }
  510.         while (n > 2000);
  511.  
  512.         dm = (int) (ceil (r * 1.0 * q / 100000));
  513.         d = rnd.uniform (dm, 2 * dm);
  514.  
  515.         generatePoints ();
  516.         generateQueries ();
  517.         generateDrivers ();
  518.         generateMatrices ();
  519.     }
  520.  
  521.     void write (FILE * fout = stdout)
  522.     {
  523.         fprintf (fout, "%u\n", seed);
  524.         fprintf (fout, "%d %d %d %d\n", a, g, q, d);
  525.         for (int i = 0; i < (int) point.size (); i++)
  526.         {
  527.             fprintf (fout, "%d %d\n", point[i].x, point[i].y);
  528.         }
  529.         for (int i = 0; i < (int) query.size (); i++)
  530.         {
  531.             fprintf (fout, "%d %d %d\n",
  532.                 query[i].from,
  533.                 query[i].to,
  534.                 query[i].moment.value);
  535.         }
  536.         for (int i = 0; i < (int) driver.size (); i++)
  537.         {
  538.             fprintf (fout, "%d %d %d\n",
  539.                 driver[i].garage,
  540.                 driver[i].momentStart.value,
  541.                 driver[i].momentFinish.value);
  542.         }
  543.         for (int i = 0; i < n; i++)
  544.         {
  545.             for (int j = 0; j < n; j++)
  546.             {
  547.                 fprintf (fout, "%d%c",
  548.                     gdist[i][j], "\n "[j + 1 < n]);
  549.             }
  550.         }
  551.         for (int i = 0; i < n; i++)
  552.         {
  553.             for (int j = 0; j < n; j++)
  554.             {
  555.                 fprintf (fout, "%d%c",
  556.                     gtime[i][j].value, "\n "[j + 1 < n]);
  557.             }
  558.         }
  559.     }
  560.  
  561.     void read (InStream & stream)
  562.     {
  563.         a = stream.readInt ();
  564.         g = stream.readInt ();
  565.         q = stream.readInt ();
  566.         n = a + g + q;
  567.         d = stream.readInt ();
  568.  
  569.         point = vector <Point> (n);
  570.         for (int i = 0; i < n; i++) // vertices
  571.         {
  572.             point[i].x = stream.readInt ();
  573.             point[i].y = stream.readInt ();
  574.         }
  575.  
  576.         query = vector <Query> (q);
  577.         for (int i = 0; i < q; i++) // queries
  578.         {
  579.             query[i].from = stream.readInt ();
  580.             query[i].to = stream.readInt ();
  581.             query[i].moment = seconds (stream.readInt ());
  582.         }
  583.  
  584.         driver = vector <Driver> (d);
  585.         for (int i = 0; i < d; i++) // drivers
  586.         {
  587.             driver[i].garage = stream.readInt ();
  588.             driver[i].momentStart = seconds (stream.readInt ());
  589.             driver[i].momentFinish = seconds (stream.readInt ());
  590.         }
  591.  
  592.         gdist = vector <vector <int> > (n, vector <int> (n));
  593.         for (int i = 0; i < n; i++) // distances
  594.         {
  595.             for (int j = 0; j < n; j++)
  596.             {
  597.                 gdist[i][j] = stream.readInt ();
  598.             }
  599.         }
  600.  
  601.         gtime = vector <vector <Time> > (n, vector <Time> (n));
  602.         for (int i = 0; i < n; i++) // travel times
  603.         {
  604.             for (int j = 0; j < n; j++)
  605.             {
  606.                 gtime[i][j] = seconds (stream.readInt ());
  607.             }
  608.         }
  609.     }
  610.  
  611.     bool isClientFromAirport (int i) const
  612.     {
  613.         return query[i].from < a;
  614.     }
  615.  
  616.     bool isClientToAirport (int i) const
  617.     {
  618.         return query[i].to < a;
  619.     }
  620.  
  621.     static const int SALARY;
  622.     static const int PENALTY;
  623.     static const Time PICK_TIME;
  624.     static const Time DROP_TIME;
  625.     static const Time MAX_DRIVING_TIME;
  626.     static const Time MAX_EXTRA_TIME;
  627.  
  628.     int64_t distanceOptimistic ()
  629.     {
  630.         int64_t res = 0;
  631.         for (int i = 0; i < q; i++)
  632.         {
  633.             res += gdist[query[i].from][query[i].to];
  634.         }
  635.         return res;
  636.     }
  637.  
  638.     int driversOptimistic ()
  639.     {
  640.         int64_t totalTime = 0;
  641.         for (int i = 0; i < q; i++)
  642.         {
  643.             totalTime += gtime[query[i].from][query[i].to].value;
  644.         }
  645.         return ceil (totalTime * 1.0 / MAX_DRIVING_TIME.value);
  646.     }
  647.  
  648.     int64_t expensesOptimistic ()
  649.     {
  650.         return distanceOptimistic () +
  651.             SALARY * 1LL * driversOptimistic ();
  652.     }
  653.  
  654.     enum CLIENT_STATE {WAITING, MOVING, DROPPED};
  655.     static int const NA = -1;
  656.  
  657.     vector <CLIENT_STATE> clientState;
  658.     vector <int> clientCar;
  659.  
  660.     vector <Time> driverMoment;
  661.     vector <Time> driverTotalTime;
  662.     vector <COMMAND> driverPreviousCommand;
  663.     vector <int> driverPos;
  664.     vector <pair <int, int> > driverClient;
  665.  
  666.     void pickClient (int i, int j, int k, Time moment)
  667.     {
  668.         if (i < 0 || q <= i)
  669.         { // CHK_QUERY_BOUNDS
  670.             quitf (_wa, "driver %d "
  671.                 "after %d actions: "
  672.                 "invalid client %d",
  673.                 j, k, i);
  674.         }
  675.         if (clientState[i] != WAITING)
  676.         {
  677.             quitf (_wa, "driver %d "
  678.                 "after %d actions: "
  679.                 "picking client %d "
  680.                 "who is not waiting",
  681.                 j, k, i);
  682.         }
  683.         if (isClientFromAirport (i) &&
  684.             moment != query[i].moment)
  685.         { // CHK_MOMENT_FROM_AIRPORT
  686.             quitf (_wa, "driver %d "
  687.                 "after %d actions: "
  688.                 "picking client %d "
  689.                 "at moment %d instead "
  690.                 "of moment %d", j, k, i,
  691.                 moment.value,
  692.                 query[i].moment.value);
  693.         }
  694.         if (isClientToAirport (i))
  695.         {
  696.             Time maxDuration = PICK_TIME +
  697.                 gtime[query[i].from][query[i].to] +
  698.                 DROP_TIME + MAX_EXTRA_TIME;
  699.             Time actualDuration = query[i].moment - moment;
  700.             if (actualDuration > maxDuration)
  701.             { // CHK_DURATION_TO_AIRPORT
  702.                 quitf (_wa, "driver %d "
  703.                     "after %d actions: "
  704.                     "picking client %d "
  705.                     "at moment %d means "
  706.                     "total query time %d, "
  707.                     "but maximum allowed "
  708.                     "time is %d", j, k, i,
  709.                     moment.value,
  710.                     actualDuration.value,
  711.                     maxDuration.value);
  712.             }
  713.         }
  714.         clientState[i] = MOVING;
  715.         clientCar[i] = j;
  716.  
  717.         if (driverClient[j].first == NA)
  718.         {
  719.             driverClient[j].first = i;
  720.         }
  721.         else if (driverClient[j].second == NA)
  722.         {
  723.             driverClient[j].second = i;
  724.         }
  725.         else
  726.         { // CHK_DRIVER_CAPACITY
  727.             quitf (_wa, "driver %d "
  728.                 "after %d actions: "
  729.                 "picking client %d "
  730.                 "when clients %d "
  731.                 "and %d are in the car",
  732.                 j, k, i,
  733.                 driverClient[j].first,
  734.                 driverClient[j].second);
  735.         }
  736.  
  737.         if (driverClient[j].first != NA &&
  738.             driverClient[j].second != NA)
  739.         {
  740.             int i1 = driverClient[j].first;
  741.             int i2 = driverClient[j].second;
  742.             if (isClientToAirport (i1) !=
  743.                 isClientToAirport (i2))
  744.             { // CHK_TWO_SAME_TYPE
  745.                 quitf (_wa, "driver %d "
  746.                     "after %d actions: "
  747.                     "clients %d and %d "
  748.                     "in the car are of "
  749.                     "different types",
  750.                     j, k + 1, i1, i2);
  751.             }
  752.             if (isClientToAirport (i1) &&
  753.                 isClientToAirport (i2) &&
  754.                 query[i1].to != query[i2].to)
  755.             { // CHK_TWO_TO_AIRPORT_ID
  756.                 quitf (_wa, "driver %d "
  757.                     "after %d actions: "
  758.                     "clients %d and %d "
  759.                     "in the car are going to "
  760.                     "different airports "
  761.                     "%d and %d",
  762.                     j, k + 1, i1, i2,
  763.                     query[i1].to,
  764.                     query[i2].to);
  765.             }
  766.             if (isClientFromAirport (i1) &&
  767.                 isClientFromAirport (i2) &&
  768.                 query[i1].from != query[i2].from)
  769.             { // CHK_TWO_FROM_AIRPORT_ID
  770.                 quitf (_wa, "driver %d "
  771.                     "after %d actions: "
  772.                     "clients %d and %d "
  773.                     "in the car are taken from "
  774.                     "different airports "
  775.                     "%d and %d",
  776.                     j, k + 1, i1, i2,
  777.                     query[i1].from,
  778.                     query[i2].from);
  779.             }
  780.             if (isClientFromAirport (i1) &&
  781.                 isClientFromAirport (i2) &&
  782.                 query[i1].moment != query[i2].moment)
  783.             { // CHK_TWO_FROM_AIRPORT_MOMENT
  784.                 quitf (_wa, "driver %d "
  785.                     "after %d actions: "
  786.                     "clients %d and %d "
  787.                     "in the car have arrived at "
  788.                     "the airport at "
  789.                     "different moments %d and %d",
  790.                     j, k + 1, i1, i2,
  791.                     query[i1].moment.value,
  792.                     query[i2].moment.value);
  793.             }
  794.         }
  795.     }
  796.  
  797.     void dropClient (int i, int j, int k, Time moment)
  798.     {
  799.         if (i < 0 || q <= i)
  800.         { // CHK_QUERY_BOUNDS
  801.             quitf (_wa, "driver %d "
  802.                 "after %d actions: "
  803.                 "invalid client %d",
  804.                 j, k, i);
  805.         }
  806.         if (clientState[i] != MOVING)
  807.         {
  808.             quitf (_wa, "driver %d "
  809.                 "after %d actions: "
  810.                 "dropping client %d "
  811.                 "who is not moving",
  812.                 j, k, i);
  813.         }
  814.         if (driverClient[j].first == i)
  815.         {
  816.             driverClient[j].first = NA;
  817.         }
  818.         else if (driverClient[j].second == i)
  819.         {
  820.             driverClient[j].second = NA;
  821.         }
  822.         else
  823.         {
  824.             quitf (_wa, "driver %d "
  825.                 "after %d actions: "
  826.                 "dropping client %d "
  827.                 "who is not in the car",
  828.                 j, k, i);
  829.         }
  830.  
  831.         if (driverPos[j] != query[i].to)
  832.         {
  833.             quitf (_wa, "driver %d "
  834.                 "after %d actions: "
  835.                 "dropping client %d "
  836.                 "at %d instead of %d",
  837.                 j, k, i,
  838.                 driverPos[j],
  839.                 query[i].to);
  840.         }
  841.  
  842.         Time finishMoment = moment + DROP_TIME;
  843.         if (isClientFromAirport (i))
  844.         {
  845.             Time maxDuration = PICK_TIME +
  846.                 gtime[query[i].from][query[i].to] +
  847.                 DROP_TIME + MAX_EXTRA_TIME;
  848.             Time actualDuration = finishMoment - query[i].moment;
  849.             if (actualDuration > maxDuration)
  850.             { // CHK_DURATION_FROM_AIRPORT
  851.                 quitf (_wa, "driver %d "
  852.                     "after %d actions: "
  853.                     "dropping client %d "
  854.                     "until moment %d means "
  855.                     "total query time %d, "
  856.                     "but maximum allowed "
  857.                     "time is %d", j, k, i,
  858.                     finishMoment.value,
  859.                     actualDuration.value,
  860.                     maxDuration.value);
  861.             }
  862.         }
  863.         if (isClientToAirport (i) &&
  864.             finishMoment > query[i].moment)
  865.         { // CHK_MOMENT_TO_AIRPORT
  866.             quitf (_wa, "driver %d "
  867.                 "after %d actions: "
  868.                 "dropping client %d "
  869.                 "until moment %d, but "
  870.                 "must arrive no later "
  871.                 "than moment %d",
  872.                 j, k, i,
  873.                 finishMoment.value,
  874.                 query[i].moment.value);
  875.         }
  876.         clientState[i] = DROPPED;
  877.     }
  878.  
  879.     SolutionResult expensesOfSolution (const Solution & solution)
  880.     {
  881.         clientState = vector <CLIENT_STATE> (q);
  882.         clientCar = vector <int> (q);
  883.         for (int i = 0; i < q; i++)
  884.         {
  885.             clientState[i] = WAITING;
  886.             clientCar[i] = NA;
  887.         }
  888.  
  889.         driverMoment = vector <Time> (d);
  890.         driverTotalTime = vector <Time> (d);
  891.         driverPreviousCommand = vector <COMMAND> (d);
  892.         driverPos = vector <int> (d);
  893.         driverClient = vector <pair <int, int> > (d);
  894.         for (int j = 0; j < d; j++)
  895.         {
  896.             driverMoment[j] = driver[j].momentStart;
  897.             driverTotalTime[j] = seconds (0);
  898.             driverPreviousCommand[j] = NO_COMMAND;
  899.             driverPos[j] = driver[j].garage;
  900.             driverClient[j].first = NA;
  901.             driverClient[j].second = NA;
  902.         }
  903.  
  904.         if ((int) solution.instruction.size () != d)
  905.         {
  906.             quitf (_pe, "got %d drivers instead of %d",
  907.                 (int) solution.instruction.size (), d);
  908.         }
  909.         int64_t res = 0;
  910.         int driversHired = 0;
  911.         for (int j = 0; j < d; j++)
  912.         {
  913.             const vector <Instruction> & curList =
  914.                 solution.instruction[j];
  915.             int curListLength = (int) curList.size ();
  916.             if (curListLength > 0)
  917.             {
  918.                 res += SALARY;
  919.                 driversHired++;
  920.             }
  921.             for (int k = 0; k < curListLength; k++)
  922.             {
  923.                 const Instruction & cur = curList[k];
  924.                 Time moment = cur.moment;
  925.                 if (moment < driverMoment[j])
  926.                 { // CHK_TIME_FLOW
  927.                     quitf (_wa, "driver %d "
  928.                         "after %d actions: "
  929.                         "free at moment %d, but next "
  930.                         "action requested at moment %d",
  931.                         j, k, driverMoment[j].value,
  932.                         moment.value);
  933.                 }
  934.                 if (cur.command == MOVE)
  935.                 {
  936.                     if (driverPreviousCommand[j] == MOVE)
  937.                     { // CHK_NO_INTERMEDIATE
  938.                         quitf (_wa, "driver %d "
  939.                             "after %d actions: "
  940.                             "next and previous "
  941.                             "actions are move "
  942.                             "commands", j, k);
  943.                     }
  944.                     int to = cur.arg1;
  945.                     if (to < 0 || n <= to)
  946.                     { // CHK_VERTEX_BOUNDS
  947.                         quitf (_wa, "driver %d "
  948.                             "after %d actions: "
  949.                             "invalid destination %d",
  950.                             j, k, to);
  951.                     }
  952.                     if (to == driverPos[j])
  953.                     { // CHK_DIFF_VERTEX
  954.                         quitf (_wa, "driver %d "
  955.                             "after %d actions: "
  956.                             "moving from %d to itself",
  957.                             j, k, driverPos[j]);
  958.                     }
  959.                     Time duration =
  960.                         gtime[driverPos[j]][to];
  961.                     res += gdist[driverPos[j]][to];
  962.                     driverTotalTime[j] += duration;
  963.                     driverMoment[j] = moment + duration;
  964.                     driverPos[j] = to;
  965.                 }
  966.                 else if (cur.command == PICK1 ||
  967.                     cur.command == PICK2)
  968.                 {
  969.                     pickClient (cur.arg1, j, k, moment);
  970.                     if (cur.command == PICK2)
  971.                     {
  972.                         pickClient (cur.arg2,
  973.                             j, k, moment);
  974.                     }
  975.                     driverMoment[j] = moment + PICK_TIME;
  976.                 }
  977.                 else if (cur.command == DROP1 ||
  978.                     cur.command == DROP2)
  979.                 {
  980.                     dropClient (cur.arg1, j, k, moment);
  981.                     if (cur.command == DROP2)
  982.                     {
  983.                         dropClient (cur.arg2,
  984.                             j, k, moment);
  985.                     }
  986.                     driverMoment[j] = moment + DROP_TIME;
  987.                 }
  988.                 else
  989.                 {
  990.                     ensure (false);
  991.                 }
  992.                 driverPreviousCommand[j] = cur.command;
  993.                 if (driverMoment[j] > driver[j].momentFinish)
  994.                 {
  995.                     quitf (_wa, "driver %d "
  996.                         "after %d actions: "
  997.                         "free at moment %d, but "
  998.                         "should end work at moment %d",
  999.                         j, k + 1,
  1000.                         driverMoment[j].value,
  1001.                         driver[j].momentFinish.value);
  1002.                 }
  1003.                 if (driverTotalTime[j] > MAX_DRIVING_TIME)
  1004.                 { // CHK_DRIVER_SAFETY
  1005.                     quitf (_wa, "driver %d "
  1006.                         "after %d actions: "
  1007.                         "total driving time is %d, but "
  1008.                         "should be at most %d", j, k + 1,
  1009.                         driverTotalTime[j].value,
  1010.                         MAX_DRIVING_TIME.value);
  1011.                 }
  1012.             }
  1013.         }
  1014.  
  1015.         for (int j = 0; j < d; j++)
  1016.         {
  1017.             if (driverPos[j] != driver[j].garage)
  1018.             {
  1019.                 quitf (_wa, "driver %d ended "
  1020.                     "the day at %d instead of %d",
  1021.                     j, driverPos[j], driver[j].garage);
  1022.             }
  1023.         }
  1024.  
  1025.         int queriesMissed = 0;
  1026.         for (int i = 0; i < q; i++)
  1027.         {
  1028.             if (clientState[i] == WAITING)
  1029.             {
  1030.                 res += PENALTY;
  1031.                 queriesMissed++;
  1032.             }
  1033.             else if (clientState[i] != DROPPED)
  1034.             {
  1035.                 quitf (_wa, "client %d ended "
  1036.                     "the day in car %d",
  1037.                     i, clientCar[i]);
  1038.             }
  1039.         }
  1040.         return SolutionResult (res, queriesMissed, q, driversHired, d);
  1041.     }
  1042. };
  1043.  
  1044. const Point Test::origin           = Point  (0, 0);
  1045. const int   Test::SALARY           =        300000; // CONST_SALARY
  1046. const int   Test::PENALTY          =       1500000; // CONST_PENALTY
  1047. const Time  Test::PICK_TIME        = seconds (600); // CONST_PICKUP
  1048. const Time  Test::DROP_TIME        = seconds (600); // CONST_DROPOFF
  1049. const Time  Test::MAX_DRIVING_TIME = hours     (9); // CONST_DRIVER_SAFETY
  1050. const Time  Test::MAX_EXTRA_TIME   = minutes  (60); // CONST_EXTRA_TIME
  1051.  
  1052. int main (int argc, char * argv [])
  1053. {
  1054.     setName ("checker for problem \"transfer\"");
  1055.  
  1056.     registerTestlibCmd (argc, argv);
  1057.  
  1058.     int64_t seed = inf.readLong ();
  1059.  
  1060.     Test test;
  1061. //  test.read (inf);
  1062.     test.generate ((unsigned) (seed));
  1063.  
  1064.     int64_t seedSolution = ouf.readLong ();
  1065.     ouf.readEoln ();
  1066.     if (seed != seedSolution)
  1067.     {
  1068.         quitf (_pe, "seed (first line) does not match input");
  1069.     }
  1070.  
  1071.     Solution solution;
  1072.     solution.read (ouf);
  1073.  
  1074.     double opt = test.expensesOptimistic ();
  1075.     SolutionResult res = test.expensesOfSolution (solution);
  1076.     double actual = res.expenses;
  1077.  
  1078. /*
  1079.     bool testingPolygon = true;
  1080.     // statistics to choose better constants
  1081.     double optDistance = test.distanceOptimistic ();
  1082.     double optDrivers = test.driversOptimistic ();
  1083.     double optDistancePercent = optDistance * 100.0 / opt;
  1084.     quitf (testingPolygon ? _ok : _pc (opt * 1000.0 / actual),
  1085.         "opt = %.0lf: %.0lf%% for average path %.0lf and "
  1086.         "%.0lf/%.0lf drivers; actual = %.0lf, ratio = %.3lf",
  1087.         opt, optDistancePercent, optDistance / test.q,
  1088.         optDrivers, test.d * 1.0, actual, opt / actual);
  1089. */
  1090.     double score = opt * 1000.0 / actual;
  1091.     // shorter comment
  1092.     quitp (score, "%.0lf/%.0lf: miss %d/%d=q, hire %d/%d=d",
  1093.         opt, actual, res.queriesMissed, res.q, res.driversHired, res.d);
  1094. /*
  1095.     // longer comment
  1096.     quitp (score, "optimistic %.0lf, actual %.0lf: %d/%d queries missed, "
  1097.         "%d/%d drivers hired, score = %.3lf",
  1098.         opt, actual, res.queriesMissed, res.q,
  1099.         res.driversHired, res.d, score);
  1100. */
  1101.  
  1102.     assert (false);
  1103.     return _fail;
  1104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement