#include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> using namespace std; typedef struct node{ char ch[5]; bool fg; vector<int> fa; //保存外界输入的信号编号 vector<int> pre; //保存依赖于其他电路门输出的输入信号 vector<int> w; }node; bool deal(const vector<node> &nodelist, vector<int> &ind, int num, vector<int> &dlist) { //q暂存拓扑排序的部分序列 queue<int> q; int i,j; for (i = 1; i <= num; ++i) { //入度为0的门无需依赖于其他门,放入q if (ind[i] == 0) { q.push(i); } } while (q.empty() == false) { //队首的门的编号放入拓扑序列 dlist.push_back(q.front()); //取出排在队首的门的编号 node temp = nodelist[q.front()]; q.pop(); //对下一个门的入度减一 for (i = 0; i < temp.w.size(); ++i) { //若下一个门的入度为0,放入q if (--ind[temp.w[i]] == 0) { q.push(temp.w[i]); } } } return dlist.size() == num; } void solve(vector<node> &nodelist, const vector<int> &dlist, int cnt, const vector<vector<int>> &ins, const vector<int> &ousnum, const vector<vector<int>> &ous) { int i,j; for (int si = 0; si < cnt; ++si) { //根据拓扑序列,使用输入得出输出 for (int ni = 0; ni < dlist.size(); ++ni) { node temp = nodelist[dlist[ni]]; //根据门的类型分别进行处理 if (temp.ch[0] == 'N' && temp.ch[2] == 'T') //非门NOT { if (temp.fa.empty() == true) temp.fg = (!nodelist[temp.pre[0]].fg); else temp.fg = (!ins[si][temp.fa[0]]); } else if (temp.ch[0] == 'A') //与门AND { temp.fg = true; for (i = 0; i < temp.fa.size(); ++i) { temp.fg &= ins[si][temp.fa[i]]; } for (i = 0; i < temp.pre.size(); ++i) { temp.fg &= nodelist[temp.pre[i]].fg; } } else if (temp.ch[0] == 'O') //或门OR { temp.fg = false; for (i = 0; i < temp.fa.size(); ++i) { temp.fg |= ins[si][temp.fa[i]]; } for (i = 0; i < temp.pre.size(); ++i) { temp.fg |= nodelist[temp.pre[i]].fg; } } else if (temp.ch[0] == 'X') //异或门XOR { temp.fg = false; for (i = 0; i < temp.fa.size(); ++i) { temp.fg ^= ins[si][temp.fa[i]]; } for (i = 0; i < temp.pre.size(); ++i) { temp.fg ^= nodelist[temp.pre[i]].fg; } } else if (temp.ch[0] == 'N' && temp.ch[1] == 'A') //与非门NAND { temp.fg = true; for (i = 0; i < temp.fa.size(); ++i) { temp.fg &= ins[si][temp.fa[i]]; } for (i = 0; i < temp.pre.size(); ++i) { temp.fg &= nodelist[temp.pre[i]].fg; } temp.fg = !temp.fg; //先算与运算,最后取反 } else if (temp.ch[0] == 'N' && temp.ch[2] == 'R') //或非门NOR { temp.fg = false; for (i = 0; i < temp.fa.size(); ++i) { temp.fg |= ins[si][temp.fa[i]]; } for (i = 0; i < temp.pre.size(); ++i) { temp.fg |= nodelist[temp.pre[i]].fg; } temp.fg = !temp.fg; //先算或运算,最后取反 } nodelist[dlist[ni]].fg = temp.fg; } //依次输出 for (int k = 0; k < ousnum[si]; ++k) { int ousNo = ous[si][k]; printf("%d ", nodelist[ousNo].fg); } putchar('\n'); } } int main() { int cnt = 0; scanf("%d", &cnt); //依次处理每个问题 for (int pi = 0; pi < cnt; ++pi) { //输入输入信号的数量和电路门的数量 int insnum, num; scanf("%d%d", &insnum, &num); vector<node> nodelist(num + 1); //电路门数组 vector<int> nodeind(num + 1, 0); //电路门的入度 //对每个门的输入信号都进行输入 for (int ni = 1; ni <= num; ++ni) { int nsn; //输入电路门的类型和电路门输入信号的数量 scanf("%s %d ", nodelist[ni].ch, &nsn); //对输入的信号进行处理 for (int nsi = 0; nsi < nsn; ++nsi) { char c = getchar(); // 'I' or 'O' int snum; scanf("%d", &snum); //信号编号 getchar(); //deal with the ' ' and '\n' if (c == 'I') //外界输入的信号编号 nodelist[ni].fa.push_back(snum); else //依赖于其他电路门输出的输入信号 { nodelist[ni].pre.push_back(snum); nodelist[snum].w.push_back(ni); ++nodeind[ni]; } } } int cnt; scanf("%d", &cnt); //为每个子问题的输入信号值分配存储空间 vector<vector<int>> ins(cnt); //输入每个子问题的数据 for (int si = 0; si < cnt; ++si) { ins[si].push_back(0); for (int ii = 1; ii <= insnum; ++ii) { int sv; scanf("%d", &sv); ins[si].push_back(sv); } } vector<int> ousnum(cnt); vector<vector<int>> ous(cnt); //输入每个子问题需要输出的信号 for (int si = 0; si < cnt; ++si) { scanf("%d", &ousnum[si]); for (int k = 0; k < ousnum[si]; ++k) { int sv; scanf("%d", &sv); ous[si].push_back(sv); } } vector<int> dlist; //拓扑排序:判环 if (!deal(nodelist, nodeind, num, dlist)) { printf("LOOP\n"); continue; } solve(nodelist, dlist, cnt, ins, ousnum, ous); } return 0; }
标签:nodelist,temp,int,++,si,fg,暂存 From: https://www.cnblogs.com/rabbit1103/p/16769821.html