不难的大模拟,思路就是拓扑排序或者dfs判环,需要注意的是当一个点入度为0,说明邻接到它的点的值已经计算出来了,这时候就可以计算这个点的值了。
坑点:当为loop的时候不能break,而是应该设置标记,然后把剩下的数据都读入(不作处理),最后输出一个loop。在这里卡了两个多小时。。
#include <bits/stdc++.h> using namespace std; int Q, M, N, S; struct node { int id, func, k; vector<int> I, O, out; } e[100005]; int deg[100005], orideg[100005]; int tran(string s) { int ans = 0; for(int i = 0; i < s.size(); i++) { ans *= 10; ans += (s[i] - '0'); } return ans; } int result[100005]; queue<int> q; void calc(int id) { if(!e[id].k) return;//k为0是输入 result已经有值了 直接返回 if(e[id].func == 1) { if(e[id].I.size()) { result[id] = !result[e[id].I[0]]; } else { result[id] = !result[e[id].O[0]]; } } else if(e[id].func == 2) { int ans = 1; for(auto x : e[id].I) ans = ans & result[x]; for(auto x : e[id].O) ans = ans & result[x]; result[id] = ans; } else if(e[id].func == 3) { int ans = 0; for(auto x : e[id].I) ans = ans | result[x]; for(auto x : e[id].O) ans = ans | result[x]; result[id] = ans; } else if(e[id].func == 4) { int ans = -1; for(auto x : e[id].I) { if(ans == -1) ans = result[x]; else ans = ans ^ result[x]; } for(auto x : e[id].O) { if(ans == -1) ans = result[x]; else ans = ans ^ result[x]; } result[id] = ans; } else if(e[id].func == 5) { int ans = 1; for(auto x : e[id].I) ans = ans & result[x]; for(auto x : e[id].O) ans = ans & result[x]; result[id] = !ans; } else { int ans = 0; for(auto x : e[id].I) ans = ans | result[x]; for(auto x : e[id].O) ans = ans | result[x]; result[id] = !ans; } } int main() { cin >> Q; while(Q--) { cin >> M >> N; bool loop = 0; memset(orideg, 0, sizeof(orideg)); memset(deg, 0, sizeof(deg)); memset(result, 0, sizeof(result)); while(q.size()) q.pop(); for(int i = 0; i <= N + M + 5; i++) e[i].k = 0, e[i].id = i, e[i].I.clear(), e[i].O.clear(), e[i].out.clear(); for(int i = 1; i <= N; i++) { string FUNC; int k; cin >> FUNC; cin >> k; e[i].k = k; if(FUNC == "NOT") e[i].func = 1; else if(FUNC == "AND") e[i].func = 2; else if(FUNC == "OR") e[i].func = 3; else if(FUNC == "XOR") e[i].func = 4; else if(FUNC == "NAND") e[i].func = 5; else e[i].func = 6; for(int j = 1; j <= k; j++) { string tmp; cin >> tmp; int id = tran(tmp.substr(1)); if(tmp[0] == 'I') { e[i].I.push_back(N + id); e[N + id].out.push_back(i); orideg[i]++; } else { e[i].O.push_back(id); e[id].out.push_back(i); orideg[i]++; } } } cin >> S; vector<vector<int> > v(S); for(int i = 1; i <= S; i++) { for(int j = 1; j <= M; j++) { int tmp; cin >> tmp; v[i - 1].push_back(tmp); } } //cout << M << endl; for(int i = 1; i <= S; i++) { int s; cin >> s; for(int j = 1; j <= N + M; j++) { deg[j] = orideg[j]; result[i] = 0; } while(q.size()) q.pop(); for(int j = 0; j < v[i - 1].size(); j++) { result[N + j + 1] = v[i - 1][j]; q.push(j + 1 + N);//M个输入对应的节点入队 } bool vis[5005]; for(int j = 1; j <= N + M; j++) vis[j] = 0; int cnt = 0; while(q.size()) { if(loop) break; int now = q.front(); q.pop(); calc(now);//计算它的result for(auto x : e[now].out) { deg[x]--; if(deg[x] == 0 && (!vis[x])) { q.push(x); vis[x] = 1; cnt++; } } } if(cnt != N) { loop = 1; for(int j = 1; j <= s; j++) { int useless; cin >> useless; } } else { for(int j = 1; j <= s; j++) { int query; cin >> query; cout << result[query] << " "; } cout << endl; } } if(loop) puts("LOOP"); } return 0; }