P11601【狼人の杀戮】题解
前言
很恶心的模拟题,虽然没打这场比赛,但是赛后也没有很轻松的 A 掉。
细节处理
-
一定要读完再做操作;
(虽然我没读完就操作也有 20 pts) -
猎人死时必须带走一个人,否则就有错误;
-
女巫只有一份毒药和解药;
-
女巫只能就这个晚上死的人;
-
倒序撤回操作;
-
猎人被杀了,带走别人,被救活,被杀死,再带走别人是合法的。
写道模拟题能写出这么问题,可见我有多菜。
代码部分
#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;
}
完结撒花!