DMOJ · dmopc17c4p4

Cops and Robbers

This C++ solution uses simulation for DMOJ dmopc17c4p4 Cops and Robbers. Read the reasoning, inspect the code, or try your own test case below.

dmopc17c4p4Graphs & treesSimulationC++66 lines
Solution057of 248
Open official problem ↗ Download C++ file ↓ Search the library → Open full Code Lab ↗ Report an issue ↗

Approach

Simulation

Cops and Robbers asks for a robbery order avoiding each day's guarded bank or -1; the code constructs the matching permutation.

Graphs & trees

Problem and code

Useful links.

Written by benbenyaojifen. Try the problem first, then compare your approach with the code.

Open official problem ↗View exact source file ↗
Implementation

cops_and_robbers.cpp

C++

    #include <bits/stdc++.h>
     
    using namespace std;
     
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0);
        int n;
        cin >> n;
        vector<int> v(n + 1);
        for(int i = 1; i <= n; i++){
            cin >> v[i];
        }
        vector<int> first_occur(n + 1);
        for(int i = 1; i < v.size(); i++){
            int f = v[i];
            if(first_occur[f] == 0){
                first_occur[f] = i;
            }
        }
        vector<int> inv(n + 1);
        for(int i = 1; i < v.size(); i++){
            int d = first_occur[i];
            if(d != 0){
                inv[d] = i;
            }
        }
        vector<int> order;
        for(int i = 1; i <= n; i++){
            if(inv[i] != 0){
                order.push_back(inv[i]);
            }
        }
        //one day is guarded every day
        if(order.size() < 2){
            cout << -1 << '\n';
            exit(0);
        }
        vector<int> ans(n + 1); 
        for(int i = 0; i < order.size(); i++){
            int cur = order[i];
            int prev = order[(i + order.size() - 1) % order.size()];
            int day = first_occur[cur];
            ans[day] = prev;
        }
        vector<bool> used_bank(n + 1), used_day(n + 1);
        for(int bank : order){
            used_bank[bank] = true;
            used_day[first_occur[bank]] = true;
        }
        //assign position for banks that the gaurd never gaurded 
        vector<int> days, banks;
        for(int i = 1; i <= n; i++){
            if(!used_bank[i]) banks.push_back(i);
        }
        for(int i = 1; i <= n; i++){
            if(!used_day[i]) days.push_back(i);
        }
        for(int i = 0; i < days.size(); i++){
            ans[days[i]] = banks[i];
        }   
        for(int i = 1; i < ans.size(); i++){
             cout << ans[i] << (i == ans.size() - 1 ? "\n" : " ");
        }
        return 0;
    }
        

Did this explanation save you time? I'm a Grade 11 student building this free library to make difficult algorithms easier to understand.

Buy me a coffee ↗Keep studying →

Test this problem

Run your code here.

Paste your code, run a test case, compare the output, or trace selected values.

Full trace, comparison & stress testing ↗
StatusReady
Output
No run yet.
Diagnostics
No diagnostics yet.

Each run is isolated and has strict limits. Passing one test does not guarantee the judge will accept the solution.