Submission #434465

#TimeUsernameProblemLanguageResultExecution timeMemory
434465Valaki2T-Covering (eJOI19_covering)C++14
55 / 100
111 ms12708 KiB
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define fi first
#define se second
#define mp make_pair
#define pii pair<int, int>

int n, m, k;

vector<vector<ll> > values;
vector<vector<bool> > special_cell;
vector<pii> special_cell_list;
vector<vector<bool> > occupied;
vector<vector<bool> > checked;
vector<vector<bool> > working_on;

ll answer;

vector<pii> directions = {mp(0, 1), mp(1, 0), mp(0, -1), mp(-1, 0)};
vector<pii> directions_adjacent = {mp(0, 1), mp(1, 0), mp(0, -1), mp(-1, 0),
                                   mp(1, 1), mp(-1, -1), mp(1, -1), mp(-1, 1),
                                   mp(0, 2), mp(2, 0), mp(0, -2), mp(-2, 0)};

pair<ll, bool> backtrack(int x, int y) {
    checked[x][y] = true;
    working_on[x][y] = true;
    int occupied_cnt = 0;
    if(occupied[x+1][y]) ++occupied_cnt;
    if(occupied[x][y+1]) ++occupied_cnt;
    if(occupied[x-1][y]) ++occupied_cnt;
    if(occupied[x][y-1]) ++occupied_cnt;
    if(occupied_cnt > 1) {
        working_on[x][y] = false;
        return mp(0ll, false);
    }
    bool ok = false;
    ll maximum_value = 0;
    ll current_value = values[x][y];
    for(pii p : directions) {
        current_value += values[x + p.fi][y + p.se];
    }
    if(occupied_cnt == 1) {
        pii occupied_coords = mp(0, 0);
        for(pii p : directions) {
            if(occupied[x + p.fi][y + p.se]) {
                occupied_coords = p;
            }
            occupied[x + p.fi][y + p.se] = true;
        }
        current_value -= values[x + occupied_coords.fi][y + occupied_coords.se];
        for(pii p : directions_adjacent) {
            if((x + p.fi < 1) || (x + p.fi > n) || (y + p.se < 1) || (y + p.se > m)) continue;
            if(special_cell[x + p.fi][y + p.se] && !working_on[x + p.fi][y + p.se]) {
                pair<ll, bool> result = backtrack(x + p.fi, y + p.se);
                if(!result.se) {
                    for(pii q : directions) {
                        if(q != occupied_coords) {
                            occupied[x + q.fi][y + q.se] = false;
                        }
                    }
                    working_on[x][y] = false;
                    return mp(0ll, false);
                }
                current_value += result.fi;
                maximum_value = max(maximum_value, current_value);
            }
        }
        maximum_value = max(maximum_value, current_value);
        for(pii p : directions) {
            if(p != occupied_coords) {
                occupied[x + p.fi][y + p.se] = false;
            }
        }
        working_on[x][y] = false;
        return mp(maximum_value, true);
    } else {
        for(pii p : directions) {
            occupied[x + p.fi][y + p.se] = true;
        }
        for(pii left_out_coords : directions) {
            occupied[x + left_out_coords.fi][y + left_out_coords.se] = false;
            ll temp_value = current_value;
            current_value -= values[x + left_out_coords.fi][y + left_out_coords.se];
            bool temp_ok = true;
            for(pii p : directions_adjacent) {
                if((x + p.fi < 1) || (x + p.fi > n) || (y + p.se < 1) || (y + p.se > m)) continue;
                if(special_cell[x + p.fi][y + p.se] && !working_on[x + p.fi][y + p.se]) {
                    pair<ll, bool> result = backtrack(x + p.fi, y + p.se);
                    if(!result.se) {
                        temp_ok = false;
                        break;
                    }
                    current_value += result.fi;
                }
            }
            occupied[x + left_out_coords.fi][y + left_out_coords.se] = true;
            if(temp_ok) {
                ok = true;
                maximum_value = max(maximum_value, current_value);
            }
            current_value = temp_value;
        }
        for(pii p : directions) {
            occupied[x + p.fi][y + p.se] = false;
        }
        working_on[x][y] = false;
        if(!ok) return mp(0ll, false);
        else return mp(maximum_value, true);
    }
}

void solve() {
    cin >> n >> m;
    values.assign(1 + n + 1, vector<ll> (1 + m + 1, 0));
    special_cell.assign(1 + n + 1, vector<bool> (1 + m + 1, false));
    occupied.assign(1 + n + 1, vector<bool> (1 + m + 1, false));
    checked.assign(1 + n + 1, vector<bool> (1 + m + 1, false));
    working_on.assign(1 + n + 1, vector<bool> (1 + m + 1, false));
    for(int i = 0; i <= n + 1; ++i) {
        occupied[i][0] = true;
        occupied[i][m + 1] = true;
    }
    for(int j = 0; j <= m + 1; ++j) {
        occupied[0][j] = true;
        occupied[n + 1][j] = true;
    }
    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= m; ++j) {
            cin >> values[i][j];
        }
    }
    cin >> k;
    special_cell_list.assign(k, mp(0, 0));
    for(int i = 0; i < k; ++i) {
        cin >> special_cell_list[i].fi >> special_cell_list[i].se;
        ++special_cell_list[i].fi;
        ++special_cell_list[i].se;
        special_cell[special_cell_list[i].fi][special_cell_list[i].se] = true;
        occupied[special_cell_list[i].fi][special_cell_list[i].se] = true;
    }
    for(pii current_cell : special_cell_list) {
        if(!checked[current_cell.fi][current_cell.se]) {
            pair<ll, bool> result = backtrack(current_cell.fi, current_cell.se);
            if(!result.se) {
                cout << "No\n";
                return;
            }
            answer += result.fi;
        }
    }
    cout << answer << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    solve();
    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...