题解:P11601 『Fwb』狼人の杀戮
xuyifei0302 · · 题解
首先,看到这道题的题面,我们根据直觉可以发现这是一道大模拟。但是,这里有一种十分麻烦的操作,就是有可能在那一晚,技能输入有误。
我们来分析一下技能输入有误的情况有那些:
- 自己杀自己。
- 使用与自己职业不同的技能。
- 杀了早已死了的人
反复鞭尸。 - 同一晚发动了多次技能。
- 编号有问题。
- 女巫没有药还救人或杀人。
- 女巫救了早已死透的人。
- 女巫救了还活着的人。
- 女巫处于将死状态,却不救自己,救别人,舍己为人。
对于这种要撤销的操作,我们把前一次操作前的状态储存下来,要撤销的话就直接使用上一次的状态。
然后模拟即可。
下面是代码环节:
#include<bits/stdc++.h>
using namespace std;
int t, n, a[25];
bool last[25], jie[25], du[25], lajie[25], ladu[25], die[25], lang[25], women[25], lie[25];
set<int> st;
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> t >> n;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
if (a[i] == 4) {
jie[i] = true;
du[i] = true;
}
}
for (int kkkk = 1; kkkk <= t; kkkk ++) {
bool flag = true;
memset(lang, false, sizeof(lang));
memset(women, false, sizeof(women));
memset(lie, false, sizeof(lie));
st.clear();
for (int i = 1; i <= n; i ++) {
last[i] = die[i];
lajie[i] = jie[i];
ladu[i] = du[i];
}
int m;
cin >> m;
for (int i = 1; i <= m; i ++) {
int op, id1, id2;
cin >> op >> id1 >> id2;
if (id1 > n || id1 < 1 || id2 > n || id2 < 1) {
flag = false;
}
if (op == 0) {
if (a[id1] != 1 || lang[id1] || die[id2] || die[id1] || id1 == id2) {
flag = false;
}
die[id2] = true;
lang[id1] = true;
st.insert(id2);
} else if (op == 1) {
if (a[id1] != 4 || !du[id1] || die[id2] || women[id1] || id1 == id2 || die[id1]) {
flag = false;
}
du[id1] = false;
die[id2] = true;
women[id1] = true;
st.insert(id2);
} else if (op == 2) {
if (a[id1] != 4 || !jie[id1] || !die[id2] || women[id1] || last[id2] || last[id1]) {
flag = false;
}
if (die[id1] && id1 != id2) {
flag = false;
}
jie[id1] = false;
die[id2] = false;
women[id1] = true;
lie[id2] = false;
st.erase(id2);
} else if (op == 3) {
if (a[id1] != 3 || !die[id1] || id1 == id2 || die[id2] || last[id1] || lie[id1]) {
flag = false;
}
die[id1] = true;
die[id2] = true;
lie[id1] = true;
st.insert(id2);
}
}
for (auto i : st) {
if (a[i] == 3 && !lie[i]) {
flag = false;
}
}
if (!flag) {
cout << "Wrong\n";
for (int i = 1; i <= n; i ++) {
die[i] = last[i];
jie[i] = lajie[i];
du[i] = ladu[i];
}
continue;
}
int len = st.size();
if (len == 0) {
cout << "Safe\n";
} else {
cout << len << " ";
for (auto i : st) {
cout << i << " ";
}
cout << "\n";
}
}
return 0;
}