Submission #758245

# Submission time Handle Problem Language Result Execution time Memory
758245 2023-06-14T10:15:13 Z ProtonDecay314 Towers (NOI22_towers) C++17
6 / 100
1227 ms 66976 KB
/*
Time complexity: O(N^2 2^N) general case (which should pass 1-2)

Subtask 3
This is a rectangle (wow)
So what it looks like is this:

T---T
-T-T-
--T--
-----
--T--
-T-T-
T---T

T--T
-TT-
----
----
-TT-
T--T

We just have to construct this, essentially

Subtask 4
For this one, we go through every x-coordinate and get the 
smallest Y and largest Y
Well, we can probably sort the values by Y
and then I can keep a set of encountered Xs
// ! Warning: the set may increase the constant factor
if an X has been encountered, then don't bother with it anymore

Now do the same, but going in reverse order of Y
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

vector<bool> solve16(ll n, const vector<tuple<ll, ll>>& pos) {
    vector<ll> xs;
    vector<ll> ys;
    for(const tuple<ll, ll>& tup : pos) {
        ll x, y;
        tie(x, y) = tup;
        xs.push_back(x);
        ys.push_back(y);
    }

    
    for(ll i = 0; i < (1 << n); i++) {
        vector<bool> third_satisfied(n, false);

        ll has_bad_x_coords = false;
        for(ll targx : xs) {
            /*
            TODO count the number of towers with this x
            mark the ones in the middle as "satisfied"
            */

            ll count_towers = 0ll;
            ll min_tower_y = numeric_limits<ll>::max();
            ll max_tower_y = numeric_limits<ll>::min();
            for(ll j = 0ll; j < n; j++) {
                ll x, y;
                tie(x, y) = pos[j];
                if(x == targx) {
                    if((i >> j) & 1) {
                        count_towers++;
                        third_satisfied[j] = true;
                        min_tower_y = min(min_tower_y, y);
                        max_tower_y = max(max_tower_y, y);
                    }
                }
            }
            if(count_towers > 2ll) {
                has_bad_x_coords = true;
                break;
            }

            for(ll j = 0ll; j < n; j++) {
                ll x, y;
                tie(x, y) = pos[j];
                if(x == targx) {
                    if(min_tower_y <= y && y <= max_tower_y) {
                        third_satisfied[j] = true;
                    }
                }
            }
        }
        if(has_bad_x_coords) continue;

        ll has_bad_y_coords = false;
        for(ll targy : ys) {
            /*
            TODO count the number of towers with this y
            mark the ones in the middle as "satisfied"
            */

            ll count_towers = 0ll;
            ll min_tower_x = numeric_limits<ll>::max();
            ll max_tower_x = numeric_limits<ll>::min();
            for(ll j = 0ll; j < n; j++) {
                ll x, y;
                tie(x, y) = pos[j];
                if(y == targy) {
                    if((i >> j) & 1) {
                        count_towers++;
                        third_satisfied[j] = true;
                        min_tower_x = min(min_tower_x, x);
                        max_tower_x = max(max_tower_x, x);
                    }
                }
            }
            if(count_towers > 2ll) {
                has_bad_y_coords = true;
                break;
            }

            for(ll j = 0ll; j < n; j++) {
                ll x, y;
                tie(x, y) = pos[j];
                if(y == targy) {
                    if(min_tower_x <= x && x <= max_tower_x) {
                        third_satisfied[j] = true;
                    }
                }
            }
        }
        if(has_bad_y_coords) continue;

        if(all_of(third_satisfied.begin(), third_satisfied.end(), [](bool v) {return v;})) {
            vector<bool> ans;
            for(ll j = 0ll; j < n; j++) {
                ans.push_back((i >> j) & 1);
            }
            return ans;
        }
    }

    return *(new vector<bool>());
}

vector<bool> solve_subtask_3(ll b, ll a) {
    vector<bool> ans;

    for(ll i = 0ll; i < b; i++) {
        for(ll j = 0ll; j < a; j++) {
            ll ni = (i >= (b >> 1) ? b - i - 1ll : i);
            ll nj = (j >= (a >> 1) ? a - j - 1ll : j);
            ans.push_back(ni == nj);
        }
    }

    return ans;
}

void print_bool_vec(const vector<bool>& vec) {
    for(bool v : vec) {
        cout << v;
    }
    cout << endl;
}

bool satisfies_subtask_3(ll n, vector<tuple<ll, ll>> pos) {
    ll b, a;
    tie(b, a) = pos[n - 1];

    // Check if subtask 3
    if(a * b != n) return false;

    for(ll j = 0ll; j < a; j++) {
        for(ll i = 0ll; i < b; i++) {
            ll curx, cury;
            tie(curx, cury) = pos[i * a + j];
            if(curx != i + 1 || cury != j + 1) return false;
        }
    }

    return true;
}

vector<bool> solve_subtask_4(ll n, const vector<tuple<ll, ll>>& pos) {
    /*
    For this one, we go through every x-coordinate and get the 
    smallest Y and largest Y
    Well, we can probably sort the values by Y
    and then I can keep a set of encountered Xs
    // ! Warning: the set may increase the constant factor
    if an X has been encountered, then don't bother with it anymore

    Now do the same, but going in reverse order of Y
    */
    vector<tuple<ll, ll, ll>> spos;
    vector<bool> ans(n, false);
    spos.reserve(n);
    for(ll i = 0ll; i < n; i++) {
        ll x, y;
        tie(x, y) = pos[i];

        spos.push_back({x, y, i});
    }

    // Phase 1: increasing X
    unordered_set<ll> ys;
    sort(spos.begin(), spos.end(), [](tuple<ll, ll, ll> a, tuple<ll, ll, ll> b) {return get<0>(a) < get<0>(b);});
    for(const tuple<ll, ll, ll> cpos : spos) {
        if(ys.count(get<1>(cpos)) == 0) {
            ans[get<2>(cpos)] = true;
        }
        ys.insert(get<1>(cpos));
    }

    // Phase 2: decreasing X
    ys.clear();
    sort(spos.begin(), spos.end(), [](tuple<ll, ll, ll> a, tuple<ll, ll, ll> b) {return get<0>(a) > get<0>(b);});
    for(const tuple<ll, ll, ll> cpos : spos) {
        if(ys.count(get<1>(cpos)) == 0) {
            ans[get<2>(cpos)] = true;
        }
        ys.insert(get<1>(cpos));
    }

    return ans;
}

int main() {
    ll n;
    cin >> n;

    vector<tuple<ll, ll>> pos;
    for(ll i = 0ll; i < n; i++) {
        ll x, y;
        cin >> x >> y;
        pos.push_back({x, y});
    }

    bool subtask3 = satisfies_subtask_3(n, pos);

    if(false && subtask3) {
        ll b, a;
        tie(b, a) = pos[n - 1];

        vector<bool> ans = solve_subtask_3(b, a);
        print_bool_vec(ans);
    } else if(false && n <= 16) {
        vector<bool> ans = solve16(n, pos);
        print_bool_vec(ans);
    } else {
        // Assume subtask 4
        vector<bool> ans = solve_subtask_4(n, pos);
        print_bool_vec(ans);
    }
    
    return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Incorrect 0 ms 212 KB Output isn't correct
6 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Incorrect 0 ms 212 KB Output isn't correct
6 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 44 ms 4004 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 842 ms 41968 KB Output is correct
2 Correct 825 ms 44948 KB Output is correct
3 Correct 872 ms 44344 KB Output is correct
4 Correct 810 ms 43956 KB Output is correct
5 Correct 821 ms 43672 KB Output is correct
6 Correct 1215 ms 66872 KB Output is correct
7 Correct 1227 ms 66976 KB Output is correct
8 Correct 1205 ms 66772 KB Output is correct
9 Correct 1214 ms 66484 KB Output is correct
10 Correct 1214 ms 66736 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Incorrect 0 ms 212 KB Output isn't correct
6 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Incorrect 0 ms 212 KB Output isn't correct
6 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Incorrect 0 ms 212 KB Output isn't correct
6 Halted 0 ms 0 KB -