Submission #1273292

#TimeUsernameProblemLanguageResultExecution timeMemory
1273292anhkhoaTram (CEOI13_tram)C++20
0 / 100
1095 ms6840 KiB
#include <iostream> #include <vector> #include <set> #include <queue> #include <cmath> #include <algorithm> using namespace std; struct Seat { int row, col; Seat(int r = 0, int c = 0) : row(r), col(c) {} bool operator<(const Seat& other) const { if (row != other.row) return row < other.row; return col < other.col; } }; struct Candidate { int min_dist; // minimum squared distance to occupied seats Seat seat; Candidate(int d, Seat s) : min_dist(d), seat(s) {} bool operator<(const Candidate& other) const { if (min_dist != other.min_dist) return min_dist < other.min_dist; if (seat.row != other.seat.row) return seat.row > other.seat.row; return seat.col > other.seat.col; } }; int squared_dist(int r1, int c1, int r2, int c2) { return (r1 - r2) * (r1 - r2) + (c1 - c2) * (c1 - c2); } class TramSeating { private: int N; set<Seat> occupied; priority_queue<Candidate> candidate_heap; void update_candidates_after_enter(const Seat& new_seat) { // Check all adjacent free seats to update their min distances for (int dr = -1; dr <= 1; dr++) { for (int dc = -1; dc <= 1; dc++) { if (dr == 0 && dc == 0) continue; int r = new_seat.row + dr; int c = new_seat.col + dc; if (r >= 1 && r <= N && c >= 1 && c <= 2) { Seat neighbor(r, c); if (occupied.find(neighbor) == occupied.end()) { int new_dist = squared_dist(r, c, new_seat.row, new_seat.col); update_seat_distance(neighbor, new_dist); } } } } } void update_seat_distance(const Seat& seat, int new_dist) { // We'd need to update the heap, but since we can't efficiently update, // we'll use a lazy approach: push new candidate and ignore outdated ones candidate_heap.push(Candidate(new_dist, seat)); } int calculate_min_distance(const Seat& seat) { if (occupied.empty()) return 1e9; int min_dist = 1e9; // Check all occupied seats (this is O(M) but M <= 30,000) for (const Seat& occ : occupied) { int dist = squared_dist(seat.row, seat.col, occ.row, occ.col); if (dist < min_dist) { min_dist = dist; } if (min_dist == 1) break; // Can't get smaller } return min_dist; } public: TramSeating(int n) : N(n) {} Seat add_passenger() { if (occupied.empty()) { Seat new_seat(1, 1); occupied.insert(new_seat); // Initialize heap with all seats initialize_heap(); return new_seat; } // Find best seat using heap (lazy deletion) while (true) { Candidate best = candidate_heap.top(); candidate_heap.pop(); // Check if seat is still free and distance is still valid if (occupied.find(best.seat) != occupied.end()) continue; int actual_dist = calculate_min_distance(best.seat); if (actual_dist == best.min_dist) { // This candidate is valid occupied.insert(best.seat); update_candidates_after_enter(best.seat); return best.seat; } else { // Push updated candidate candidate_heap.push(Candidate(actual_dist, best.seat)); } } } void remove_passenger(const Seat& seat) { occupied.erase(seat); // When removing, we need to update distances of nearby seats // For simplicity, we'll just push them back to heap with recalculated distances update_candidates_after_leave(seat); } void update_candidates_after_leave(const Seat& removed_seat) { // Update all seats in nearby rows for (int r = max(1, removed_seat.row - 2); r <= min(N, removed_seat.row + 2); r++) { for (int c = 1; c <= 2; c++) { Seat seat(r, c); if (occupied.find(seat) == occupied.end()) { int dist = calculate_min_distance(seat); candidate_heap.push(Candidate(dist, seat)); } } } } void initialize_heap() { for (int r = 1; r <= N; r++) { for (int c = 1; c <= 2; c++) { Seat seat(r, c); if (occupied.find(seat) == occupied.end()) { int dist = calculate_min_distance(seat); candidate_heap.push(Candidate(dist, seat)); } } } } }; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int N, M; cin >> N >> M; TramSeating tram(N); vector<Seat> passenger_seat(M + 1); vector<bool> active(M + 1, false); int passenger_id = 0; for (int event_id = 1; event_id <= M; event_id++) { char type; cin >> type; if (type == 'E') { passenger_id++; Seat seat = tram.add_passenger(); passenger_seat[passenger_id] = seat; active[passenger_id] = true; cout << seat.row << " " << seat.col << "\n"; } else { // 'L' int p; cin >> p; if (active[p]) { tram.remove_passenger(passenger_seat[p]); active[p] = false; } } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...