P11601【狼人の杀戮】题解

· · 题解

前言

很恶心的模拟题,虽然没打这场比赛,但是赛后也没有很轻松的 A 掉。

细节处理

  1. 一定要读完再做操作;(虽然我没读完就操作也有 20 pts)

  2. 猎人死时必须带走一个人,否则就有错误;

  3. 女巫只有一份毒药和解药;

  4. 女巫只能就这个晚上死的人;

  5. 倒序撤回操作;

  6. 猎人被杀了,带走别人,被救活,被杀死,再带走别人是合法的。

写道模拟题能写出这么问题,可见我有多菜。

代码部分

#include <bits/stdc++.h>
using namespace std;
const int N = 25;
int t, n, f[N], d[N], op[N], m, a[N], b[N], fl = 0;
bool fd[N], fz[N], hp[N], v[N], vv[N];
/*
f 表示身份;
d 表示死亡时间;
fd 表示女巫是否用过毒;
fz 表示女巫是否用过解药;
hp 表示是否活着;
v 表示是否用过技能;
vv 表示前一个夜晚的死亡情况。
*/
signed main ()
{
    ios::sync_with_stdio (0), cin.tie (0), cout.tie (0);
    cin >> t >> n;
    for (int i = 1; i <= n; ++ i)
    {
        cin >> f[i];
        hp[i] = 1;
    }
    while (t --)
    {
        fl = 0;
        vector <int> dd[N];
        for (int i = 1; i <= n; ++ i)vv[i] = hp[i], v[i] = 0, dd[i].clear ();
        cin >> m;
        for (int i = 1; i <= m; ++ i)cin >> op[i] >> a[i] >> b[i];
        for (int i = 1; i <= m; ++ i)
        {
            if (a[i] < 1 || a[i] > n || b[i] < 1 || b[i] > n || f[a[i]] == 2)fl = i;
            if (op[i] == 0 && (v[a[i]] || b[i] == a[i] || ! hp[b[i]] || f[a[i]] ^ 1 || ! hp[a[i]]))fl = i;
            if (op[i] == 1 && (v[a[i]] || b[i] == a[i] || fd[a[i]] || ! hp[b[i]] || f[a[i]] ^ 4 || ! hp[a[i]]))fl = i;
            if (op[i] == 2 && (v[a[i]] || hp[b[i]] || fz[a[i]] || f[a[i]] ^ 4 || d[b[i]] ^ t || (! hp[a[i]] && b[i] ^ a[i])))fl = i;
            if (op[i] == 3 && (hp[a[i]] || v[a[i]] || b[i] == a[i] || ! hp[b[i]] || f[a[i]] ^ 3))fl = i;
            if (fl)break;
            v[a[i]] = 1;
            if (op[i] == 0)
            {
                hp[b[i]] = 0;
                d[b[i]] = t;
                if (f[b[i]] == 3)v[b[i]] = 0;
            }
            if (op[i] == 1)
            {
                fd[a[i]] = 1;
                hp[b[i]] = 0;
                d[b[i]] = t;
                if (f[b[i]] == 3)v[b[i]] = 0;
            }
            if (op[i] == 2)
            {
                fz[a[i]] = 1;
                hp[b[i]] = 1;
                d[b[i]] = 0;
            }
            if (op[i] == 3)
            {
                hp[b[i]] = 0;
                d[b[i]] = t;
            }
        }
        for (int i = 1; i <= n; ++ i)if (hp[i] - vv[i] && f[i] == 3 && ! v[i])fl = n + 1;
        if (fl)
        {
            cout << "Wrong\n";
            for (int i = fl - 1; i; -- i)
            {
                if (op[i] == 0)
                {
                    hp[b[i]] = 1;
                    d[b[i]] = 0;
                }
                if (op[i] == 1)
                {
                    fd[a[i]] = 0;
                    hp[b[i]] = 1;
                    d[b[i]] = 0;
                }
                if (op[i] == 2)
                {
                    fz[a[i]] = 0;
                    hp[b[i]] = 0;
                    d[b[i]] = 0;
                }
                if (op[i] == 3)
                {
                    hp[b[i]] = 1;
                    d[b[i]] = 0;
                }
            }
            continue;
        }
        int c = 0, ans[N];
        for (int i = 1; i <= n; ++ i)if (hp[i] - vv[i])ans[++ c] = i;
        if (c)cout << c << ' ';
        else cout << "Safe";
        for (int i = 1; i <= c; ++ i)cout << ans[i] << ' ';
        cout << '\n';
    }
    return 0;
}

完结撒花!