제출 #1022270

#제출 시각아이디문제언어결과실행 시간메모리
1022270TroySerPalembang Bridges (APIO15_bridge)C++17
100 / 100
226 ms26808 KiB
// median?
#include <bits/stdc++.h>
 
using namespace std;
 
const long long int INF = 1e18;
 
long long int K, N;
long long int build1, build2;
char zone1, zone2;

long long int Dmin = 0;
 
struct Place {
    char zone;
    long long int building;
};

vector<pair<Place, Place> > people;
vector<long long int> person;
vector<long long int> pref;

bool cmp(pair<Place, Place> &a, pair<Place, Place> &b) {
    return (a.first.building + a.second.building) < (b.first.building + b.second.building);
}
 
long long int cost(long long int currK) {
    long long int currMin = 0;
    for (int j = 0; j < people.size(); j++) {
        currMin += abs(people[j].first.building - currK);
        currMin++;
        currMin += abs(people[j].second.building - currK);
    }
    return currMin;
}

class MedianFinder {
    private:
        multiset<long long int, greater<long long int>> leftSet;
        multiset<long long int> rightSet;
    public:
        long long int leftSum;
        long long int rightSum;

        MedianFinder() {
            leftSum = 0;
            rightSum = 0;
        }
        void insert(long long int x) {
            int median = (leftSet.size() ? *leftSet.begin() : 1000000001);

            if (x <= median) {
                leftSet.insert(x);
                leftSum += x;
            } else {
                rightSet.insert(x);
                rightSum += x;
            }

            if (rightSet.size() + 1 < leftSet.size()) { // there's too little elements
                long long int nxt = *leftSet.begin();
                rightSet.insert(nxt);
                leftSet.erase(leftSet.begin());
                leftSum -= nxt;
                rightSum += nxt;
            } else if (leftSet.size() < rightSet.size()) {
                long long int nxt = *rightSet.begin();
                leftSet.insert(nxt);
                rightSet.erase(rightSet.begin());
                leftSum += nxt;
                rightSum -= nxt;
            }
        }

        void print() {
            cout << "Left: ";
            for (auto l: leftSet) {
                cout << l << ", ";
            }
            cout << "\n";
            cout << "Right: ";
            for (auto l: rightSet) {
                cout << l << ", ";
            }
            cout << "\n";
        }
};

int main() {
    cin >> K >> N;

    for (int i = 0; i < N; i++) {
        cin >> zone1 >> build1 >> zone2 >> build2;
        if (zone1 == zone2) {
            Dmin += abs(build2 - build1);
        } else {
            people.push_back(make_pair(
                (Place){zone1, build1}, 
                (Place){zone2, build2}
            ));
            person.push_back(build1);
            person.push_back(build2);
        }
    }
 
    int M = person.size();
    long long int possibleMin = INF;

    if (M == 0) {
        possibleMin = 0;
        cout << Dmin << "\n";
    } else if (K == 1) {
        sort(person.begin(), person.end());
        for (int i = M/2; i <= M/2 + 1; i++) {
            possibleMin = min(possibleMin, cost(person[i]));
        }
        cout << possibleMin + Dmin << "\n";
    }
    else {
        sort(people.begin(), people.end(), cmp);

        int actualPeople = people.size();
        Dmin += actualPeople; // each person needs to cross the bridge
        
        MedianFinder mf = MedianFinder();

        pref.resize(actualPeople + 1);

        for (int i = 1; i < actualPeople + 1; i++) {
            mf.insert(people[i-1].first.building);
            mf.insert(people[i-1].second.building);
            pref[i] = mf.rightSum - mf.leftSum;
            // mf.print();
        }

        MedianFinder mf1 = MedianFinder();

        long long int ans = pref[actualPeople];

        for (int i = actualPeople; i; i--) {
            mf1.insert(people[i-1].first.building);
            mf1.insert(people[i-1].second.building);
            ans = min(ans, mf1.rightSum - mf1.leftSum + pref[i - 1]);
        }

        cout << Dmin + ans << "\n";
    }
}

컴파일 시 표준 에러 (stderr) 메시지

bridge.cpp: In function 'long long int cost(long long int)':
bridge.cpp:29:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<Place, Place> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   29 |     for (int j = 0; j < people.size(); j++) {
      |                     ~~^~~~~~~~~~~~~~~
#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...