Submission #824846

#TimeUsernameProblemLanguageResultExecution timeMemory
824846QwertyPiCop and Robber (BOI14_coprobber)C++14
100 / 100
1371 ms9612 KiB
#include "coprobber.h" #include <bits/stdc++.h> #pragma GCC optimize("unroll-loops") #pragma GCC optimize("Ofast") using namespace std; struct state{ int u, v, t; int operator()() const { return u * MAX_N * 2 + v * 2 + t; } string print() const { string r; r += "("; r += to_string(u); r += ", "; r += to_string(v); r += ", "; r += to_string(t); r += ")"; return r; } }; int id(int u, int v, int t){ return u * MAX_N * 2 + v * 2 + t; } int N; bool w[MAX_N * MAX_N * 2]; int nxt[MAX_N * MAX_N * 2]; int deg[MAX_N * MAX_N * 2], r_deg[MAX_N * MAX_N * 2]; bool added[MAX_N * MAX_N * 2]; bool A[MAX_N][MAX_N]; void add_edge(int u, int v){ // cout << "Edge: " << u.print() << " -> " << v.print() << endl; if(w[v] == true) deg[u]++; r_deg[u]++; } int pos = -1; int start(int N, bool A[MAX_N][MAX_N]) { ::N = N; for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ ::A[i][j] = A[i][j]; } } for(int u = 0; u < N; u++){ for(int v = 0; v < N; v++){ for(int t = 0; t < 2; t++){ state st {u, v, t}; if(u == v) w[st()] = true; } } } for(int u = 0; u < N; u++){ for(int v = 0; v < N; v++){ for(int t = 0; t < 2; t++){ if(u == v) continue; if(t == 0){ for(int i = 0; i < N; i++){ if(A[u][i] || i == u){ add_edge(id(u, v, t), id(i, v, !t)); } } }else{ for(int i = 0; i < N; i++){ if(A[v][i]){ add_edge(id(u, v, t), id(u, i, !t)); } } } } } } vector<int> det; for(int u = 0; u < N; u++){ for(int v = 0; v < N; v++){ for(int t = 0; t < 2; t++){ state st {u, v, t}; bool alr_win = false; if(t == 0){ for(int i = 0; i < N; i++){ if(A[u][i] && i == v) alr_win = true; } } if(u != v && (r_deg[st()] == deg[st()] || alr_win)){ det.push_back(st()); added[st()] = true; } } } } while(det.size()){ int k = det.back(); det.pop_back(); int u = k / 2 / MAX_N; int v = k / 2 % MAX_N; int t = k % 2; int st = id(u, v, t); if(t == 0){ bool exist_win = false; for(int i = 0; i < N; i++){ if(A[u][i] || i == u){ int st2 = id(i, v, !t); exist_win |= w[st2]; if(w[st2]) nxt[st] = st2; if(exist_win) break; } } w[st] = exist_win; }else{ bool all_win = true; for(int i = 0; i < N; i++){ if(A[v][i]){ int st2 = id(u, i, !t); all_win &= w[st2]; if(!all_win) break; } } w[st] = all_win; } if(t == 0){ for(int i = 0; i < N; i++){ if(A[i][v]){ int st2 = id(u, i, 1); if(added[st2]) continue; deg[st2]++; if(deg[st2] == r_deg[st2]) added[st2] = true, det.push_back(st2); else if((!t) == 0 && w[st] == 1) added[st2] = true, det.push_back(st2); else if((!t) == 1 && w[st] == 0) added[st2] = true, det.push_back(st2); } } }else{ for(int i = 0; i < N; i++){ if(A[i][u] || i == u){ int st2 = id(i, v, 0); if(added[st2]) continue; deg[st2]++; if(deg[st2] == r_deg[st2]) added[st2] = true, det.push_back(st2); else if((!t) == 0 && w[st] == 1) added[st2] = true, det.push_back(st2); else if((!t) == 1 && w[st] == 0) added[st2] = true, det.push_back(st2); } } } } for(int i = 0; i < N; i++){ bool all_win = true; for(int j = 0; j < N; j++){ state st {i, j, 0}; all_win &= w[st()]; } if(all_win){ pos = i; return i; } } return -1; } int nextMove(int R) { state st {pos, R, 0}; int st2 = nxt[st()]; pos = st2 / 2 / MAX_N; return pos; }

Compilation message (stderr)

coprobber.cpp: In function 'void add_edge(int, int)':
coprobber.cpp:38:5: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
   38 |     if(w[v] == true) deg[u]++; r_deg[u]++;
      |     ^~
coprobber.cpp:38:32: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
   38 |     if(w[v] == true) deg[u]++; r_deg[u]++;
      |                                ^~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...