Submission #556419

#TimeUsernameProblemLanguageResultExecution timeMemory
556419JomnoiRail (IOI14_rail)C++17
30 / 100
259 ms98620 KiB
#include <bits/stdc++.h>
#define DEBUG false
#include "rail.h"
using namespace std;

const int MAX_N = 5e3 + 10;
const int INF = 1e9 + 7;

int min_dist, firstD, latestC, latestD;
int dist[MAX_N][MAX_N];
vector <pair <int, int>> L, R;
bool processed[MAX_N];

void findLocation(int N, int first, int location[], int stype[]) {
    for(int i = 1; i < N; i++) {
        dist[0][i] = dist[i][0] = getDistance(0, i);
    }

    processed[0] = true;
    location[0] = first;
    stype[0] = 1;
    
    min_dist = INF;
    for(int i = 1; i < N; i++) {
        if(min_dist > dist[0][i]) {
            min_dist = dist[0][i];
            firstD = i;
        }
    }

    processed[firstD] = true;
    location[firstD] = first + min_dist;
    stype[firstD] = 2;

    for(int i = 1; i < N; i++) {
        if(i != firstD) {
            dist[firstD][i] = dist[i][firstD] = getDistance(firstD, i);
        }
    }

    for(int i = 1; i < N; i++) {
        if(i == firstD) {
            continue;
        }

        if(dist[firstD][i] < dist[0][i]) { // it is on the left of the station 0
            location[i] = location[firstD] - dist[firstD][i];
            stype[i] = 1;
            if(location[i] < first) {
                L.emplace_back(location[i], i);
            }
            else {
                processed[i] = true;
            }
        }
        else { // it is on the right of the first station that is type D
            location[i] = first + dist[0][i];
            stype[i] = 2;
            R.emplace_back(location[i], i);
        }
    }

    sort(L.rbegin(), L.rend());
    sort(R.begin(), R.end());

    if(!L.empty()) {
        latestC = L.front().second;
        latestD = firstD;
        location[latestC] = location[firstD] - dist[firstD][latestC];
        stype[latestC] = 1;
        processed[latestC] = true;
        for(auto [distFromFirstD, idx] : L) {
            if(idx == latestC) {
                continue;
            }

            processed[idx] = true;
            dist[idx][latestC] = dist[latestC][idx] = getDistance(latestC, idx);
            if(dist[latestC][idx] < dist[latestD][idx]) {
                location[idx] = location[latestC] + dist[latestC][idx];
                stype[idx] = 2;

                for(int i = 0; i < N; i++) {
                    if(processed[i] == true) {
                        continue;
                    }

                    dist[idx][i] = dist[i][idx] = dist[latestD][i] - (location[latestD] - location[idx]);
                }
                latestD = idx;
            }
            else {
                location[idx] = location[latestD] - dist[latestD][idx];
                stype[idx] = 1;
                latestC = idx;
            }
        }
    }
    if(!R.empty()) {
        latestC = 0;
        latestD = R.front().second;
        location[latestD] = first + dist[0][latestD];
        stype[latestD] = 2;
        processed[latestD] = true;
        for(auto [distFrom0, idx] : R) {
            if(idx == latestD) {
                continue;
            }

            processed[idx] = true;
            dist[idx][latestD] = dist[latestD][idx] = getDistance(latestD, idx);

            if(DEBUG) {
                cout << "pos : " << latestC << ' ' << latestD << endl;
                cout << "dist: " << dist[latestC][idx] << ' ' << dist[latestD][idx] << endl;
            }

            if(dist[latestD][idx] < dist[latestC][idx]) {
                location[idx] = location[latestD] - dist[latestD][idx];
                stype[idx] = 1;

                for(int i = 0; i < N; i++) {
                    if(processed[i] == true) {
                        continue;
                    }

                    dist[idx][i] = dist[i][idx] = dist[latestC][i] - (location[idx] - location[latestC]);
                }
                latestC = idx;
            }
            else {
                location[idx] = location[latestC] + dist[latestC][idx];
                stype[idx] = 2;
                latestD = idx;
            }
        }
    }

    if(DEBUG) {
        for(int i = 0; i < N; i++) {
            cout << stype[i] << ' ' << location[i] << endl;
        }
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...