QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#54957#2475. Bank RobberysebinkimWA 2ms3652kbC++3.9kb2022-10-11 18:57:202022-10-11 18:57:21

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-10-11 18:57:21]
  • 评测
  • 测评结果:WA
  • 用时:2ms
  • 内存:3652kb
  • [2022-10-11 18:57:20]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using ld=double;
using vll=vector<ll>;
using vvll=vector<vector<ll>>;
#define FOR(i,a,b) for(ll i=a;i<(ll)b;++i)
#define F(n) FOR(i,0,n)
#define FF(n) FOR(j,0,n)
#define aa first
#define bb second
#define PB push_back
#define EQ(a,b) (fabs(a-b)<=(fabs(a+b)*EPS))
#define MOD ((ll)(1e9+7))
#define dbg cerr
#define dbg if(0)cerr
#define out(n) cout << n << '\n'
#define INF (1ll << 40)

#define UNSET -1
#define EMPTY 0
#define GUARD 1
#define GUARDED 2
#define STAR_WAIT 3
#define STAR_GOOD 4
#define STAR_HELP 5

bool hasGuard(ll state) {
  return state == GUARD || state == STAR_WAIT || state == STAR_GOOD || state == STAR_HELP;
}

#define MAXN 1000

ll st[MAXN];
ll helper[MAXN];
vvll g;
vvll gg;
ll par[MAXN];
ll n, k;

#define ROOT 0

ll dfsDef(ll v, ll parState, ll siblings) {
  if (g[v].empty()) {
    if (parState == STAR_WAIT) st[v] = STAR_HELP;
    else st[v] = EMPTY;
  }
  else if (g[v].size() == 1) {
    st[v] = EMPTY;
    ll childState = dfsDef(g[v][0], st[v], g[v].size());
    if (childState == EMPTY) {
      st[v] = GUARD;
      helper[g[v][0]] = v;
    }
    else if (childState == GUARD) { // like leaf
      if (parState == STAR_WAIT) st[v] = STAR_HELP;
      else st[v] = EMPTY;
    }
    else if (childState == STAR_GOOD) st[v] = GUARDED;
    else assert(0);
  }
  else { // g[v].size() > 1
    ll sibs = g[v].size();
    if (parState == STAR_GOOD) st[v] = STAR_GOOD;
    else st[v] = STAR_WAIT;
    F(g[v].size()) {
      ll cs = dfsDef(g[v][i], st[v], sibs);
      if (cs == STAR_HELP || cs == STAR_GOOD) st[v] = STAR_GOOD;

    }
    if (st[v] == STAR_WAIT) {
      st[v] = EMPTY;
    }
  }
  if (v == ROOT && (st[v] == STAR_HELP || st[v] == EMPTY)) st[v] = GUARD;
  return st[v];
}

ll getMinGuards() {
  F(n) st[i] = -2;
  dfsDef(ROOT, -2, g[ROOT].size());
  ll res = 0;
  F(n) {
    if (hasGuard(st[i])) res ++;
    if (st[i] == STAR_WAIT) assert(0);
  }
  return res;
}


void getInitState() {
  dbg << "states: " << endl;
  F(n) dbg << st[i] << ' ';
  dbg << endl;
  cout << getMinGuards() << endl;
  F(n) if (hasGuard(st[i])) cout << i << ' ';
  cout << endl;
}

ll from[MAXN];
ll dfsFindHelp(ll v, ll par) {
  from[v] = par;
  dbg << "here: " << v << endl;
  if (st[v] == STAR_HELP) {
    return v;
  }
  F(gg[v].size()) {
    if (gg[v][i] == par) continue;
    ll cur = dfsFindHelp(gg[v][i], v);
    if (cur != -1) return cur;
  }
  return -1;
}

void defend() {
  cout << "DEFEND" << endl;
  ll attacks;
  cin >> attacks;
  getInitState();

  while (attacks --) {
    ll at;
    cin >> at;
    dbg << "attack on " << at << endl;
    if (!hasGuard(st[at]))  {
      if (st[helper[at]] == GUARD) {
        cout << 1 << endl;
        cout << helper[at] << ' ' << at << endl;

        st[helper[at]] = EMPTY;
        st[at] = GUARD;
        helper[helper[at]] = at;
      } else if (st[helper[at]] == STAR_GOOD) {
        // find a path to some STAR_HELP
        dbg << "finding help" << endl;
        ll help = dfsFindHelp(at, -1);
        st[help] = EMPTY;
        st[at] = STAR_HELP;
        dbg << "done" << endl;

        vector<pair<ll,ll>> res;
        while (help != -1) {
          res.PB({help, from[help]});
          help = from[help];
        }
        res.pop_back();
        cout << res.size() << endl;
        for (auto i: res) cout << i.aa << ' ' << i.bb << endl;
      } else assert(0);
    } else {
      cout << 0 << endl;
    }
  }
}

void attack() {
  // TODO
}

int main(){
  ios::sync_with_stdio(0);cin.tie(0);

  cin >> n >> k;
  g = vvll(n);
  gg = vvll(n);
  F(n-1) {
    ll v;
    cin >> v;
    g[v].PB(i+1);
    gg[v].PB(i+1);
    gg[i+1].PB(v);
  }

  dbg << "Need at least guards: " << getMinGuards() << endl;
  if (k >= getMinGuards()) defend();
  else cout << "ATTACK" << endl;

  return 0;
}

详细

Test #1:

score: 0
Wrong Answer
time: 2ms
memory: 3652kb

input:

6 3
0 1
0 2
0 3
3 4
3 5
4

output:

DEFEND
3
0 1 2 
2
1 0
0 3
1
2 4
0

result:

wrong answer defender is trying to move a non-existant guard 2