알고리즘/softeer
Softeer - 교차로
유이얼
2022. 1. 31. 01:14
https://softeer.ai/practice/info.do?eventIdx=1&psProblemId=803
시간제한 발생 시, update time 처리 필요
- 2 ≤ N ≤ 200,000
- 모든 i(1 ≤ i ≤ N)에 대해, 0 ≤ ti ≤ 10^9
=> 10^9 만큼 처리하는 게 아니라, 200,000 만큼만 처리해야함.
#include <iostream>
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define ID front().first
#define TIME front().second
queue<pair<int, int>> seq[4];
vector<int> answer;
int cur;
const int MAX = 10E8 + 3 * 10E4;
char right(char d) {
return (d + 3) % 4;
}
bool isThere(char d) {
if (seq[d].empty()) return false;
return seq[d].TIME <= cur;
}
bool go(char d) {
return isThere(d) && !isThere(right(d));
}
bool waiting(char d) {
return isThere(d) && isThere(right(d));
}
void updateTime() {
int val = MAX;
for (int i = 0; i < 4; ++i) {
if (seq[i].empty()) continue;
if (seq[i].TIME <= cur) return;
val = min(seq[i].TIME, val);
}
cur = val;
}
int limit(char d) {
if (seq[right(d)].empty()) return MAX;
return seq[right(d)].TIME;
}
void each(char d) {
if (seq[d].TIME >= limit(d)) return;
if (seq[d].TIME > cur) return;
answer[seq[d].ID] = cur;
seq[d].pop();
}
bool progress() {
updateTime();
int count = 0;
bool pre_check[4];
for (int i = 0; i < 4; ++i) {
pre_check[i] = go(i);
count += pre_check[i];
}
if (count == 0) return false;
for (int i = 0; i < 4; ++i) {
if (!pre_check[i]) continue;
each(i);
}
++cur;
return true;
}
void solve() {
while (1) {
if (!progress()) return;
}
}
int main() {
int n;
cin >> n;
answer.resize(n, -1);
for (int i = 0; i < n; ++i) {
char dir;
int t;
cin >> t >> dir;
seq[dir - 'A'].push({ i, t });
}
solve();
for (int i = 0; i < n; ++i)
cout << answer[i] << "\n";
return 0;
}