Advertisement
dmkozyrev

acmp_1513.cpp

Feb 7th, 2018
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.09 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <vector>
  3. #include <map>
  4. #include <algorithm>
  5. #include <cstdint>
  6.  
  7. struct Worker {
  8.     int ts, floor; // Время вызова, этаж
  9.     int64_t tf; // Время высадки на первый этаж (ответ)
  10.    
  11.     Worker(int time_start = 0, int floor = 0, int64_t time_finish = -1)
  12.         : ts(time_start)
  13.         , floor(floor)
  14.         , tf(time_finish)
  15.     { }
  16. };
  17.  
  18. int main () {
  19.     freopen("input.txt", "rt", stdin);
  20.     freopen("output.txt", "wt", stdout);
  21.    
  22.     int nWorkers, nFloors;
  23.     scanf("%d %d", &nWorkers, &nFloors);
  24.    
  25.     // Читаем входные данные и заносим их в вектор:
  26.     std::vector<Worker> workers;
  27.     for (int i = 0; i < nWorkers; ++i) {
  28.         int time, floor;
  29.         scanf("%d %d", &time, &floor);
  30.         workers.push_back(Worker(time, floor));
  31.     }
  32.    
  33.     // Очередь ожидающих обработки рабочих: wait[этаж] --> список рабочих, ожидающих лифта
  34.     std::map<int, std::vector<int>> wait;
  35.    
  36.     int firstNotFinished = 0; // Первый не обработанный
  37.     int firstNotWait = 0;     // Первый не оижадющий обработки
  38.     int64_t curr_time = 0;    // Текущее время
  39.     while (firstNotFinished < nWorkers) {
  40.         // Пропускаем всех тех, кого уже обработали:
  41.         if (workers[firstNotFinished].tf != -1) {
  42.             ++firstNotFinished;
  43.             continue;
  44.         }
  45.        
  46.         // Получаем информацию о текущем активном вызове:
  47.         int64_t currWorkerTime  = workers[firstNotFinished].ts;
  48.         int64_t currWorkerFloor = workers[firstNotFinished].floor;
  49.        
  50.         // Добавляем первого необработанного в очередь:
  51.         if (firstNotFinished > firstNotWait) {
  52.             wait[currWorkerFloor].push_back(firstNotFinished);
  53.             if (firstNotFinished == firstNotWait) {
  54.                 ++firstNotWait;
  55.             }
  56.         }
  57.        
  58.         // Текущее время старта и время окончания:
  59.         curr_time = std::max(curr_time, currWorkerTime);
  60.         int64_t finish_time = curr_time + 2 * (currWorkerFloor - 1);
  61.        
  62.         // Обрабатываем тех, которые уже ожидают на этажах:
  63.         auto it = wait.begin();
  64.         while (it != wait.end()) { // Пробегаем все этажи до активного включительно
  65.             if (it->first > currWorkerFloor) { // Вышли за пределы активного этажа - выходим
  66.                 break;
  67.             }
  68.             for (const auto w : it->second) { // Забираем всех тех, которые ожидают в данный момент:
  69.                 workers[w].tf = finish_time;
  70.             }
  71.             // Переходим к следующей итерации, подчищая за собой мусор:
  72.             wait.erase(it++);
  73.         }
  74.        
  75.         // Обрабатываем тех, которые вызывают лифт в тот промежуток времени, когда лифт движется вверх-вниз:
  76.         while (firstNotWait < nWorkers) {
  77.             if (workers[firstNotWait].ts > finish_time) {
  78.                 // Лифт завершит движение вверх-вниз раньше, чем придет текущий работник - выходим
  79.                 break;
  80.             }
  81.            
  82.             if (
  83.                 workers[firstNotWait].floor > currWorkerFloor || // Работник вызывает лифт на этаже выше активного этажа, до которого поднимается лифт
  84.                 workers[firstNotWait].floor + workers[firstNotWait].ts > currWorkerFloor + (finish_time + curr_time) / 2 // Работник не успевает на лифт
  85.             ) {
  86.                 // Вносим работника в список ожидающих:
  87.                 wait[workers[firstNotWait].floor].push_back(firstNotWait);
  88.             } else {
  89.                 // Иначе работник успевает на лифт:
  90.                 workers[firstNotWait].tf = finish_time;            
  91.             }
  92.             ++firstNotWait;
  93.         }
  94.        
  95.         // Лифт закончил движение вверх-вниз:
  96.         curr_time = finish_time;
  97.     }
  98.    
  99.     // Выводим ответ:
  100.     for (auto & w : workers) {
  101.         printf("%I64d\n", w.tf);
  102.     }
  103.    
  104.     return 0;
  105. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement