202009-3(点亮数字人生)
作者:互联网
注意将题抽象成一个图的形式,同时注意w[MAXN]的使用来记录通过每个器件时的结果
//每通过一个器件维护依次w[MAXN],用来跟新所有器件的状态,最后得到一个总状态,然后根据相应的要求输出即可。
#include <bits/stdc++.h> using namespace std; const int MAXV = 505;//最多500个器件 struct Node{ int v;//边的终点编号 Node(int _v):v(_v){};//构造函数 }; vector<Node> G[MAXV];//邻接表 int w[MAXV];//边权重 string type[MAXV];//器件类型 int inDegree[MAXV]={0};//入度 bool initV[MAXV]={false};//判断是否初始化 vector<int> test_in[10005];//最多运行10000次 vector<int> test_out[10005]; bool topologicalSort(int m,int n) { int num = 0;//记录加入拓扑序列的顶点数 queue<int> q; int temp_inDegree[MAXV];//存储临时入度 memcpy(temp_inDegree,inDegree,(m+n)*sizeof(int)); for(int i=0;i<m+n;i++) { if(temp_inDegree[i]==0) q.push(i); } while(!q.empty()) { int u = q.front(); q.pop(); for(int i=0;i<G[u].size();i++) { int v = G[u][i].v; temp_inDegree[v]--; if(temp_inDegree[v]==0) q.push(v); } num++; } if(num == m+n) return true; else return false; } void calculate(int m,int n) { queue<int> q; int temp_inDegree[MAXV]; memcpy(temp_inDegree,inDegree,(m+n)*sizeof(int));//将inDegree的内容拷贝到temp_inDegree for(int i=0;i<m+n;i++) { if(temp_inDegree[i]==0) q.push(i); } while(!q.empty()) { int u = q.front(); q.pop(); for(int i=0;i<G[u].size();i++) { int v = G[u][i].v; temp_inDegree[v]--; if(!initV[v]) { w[v] = w[u]; if(type[v] == "NOT") w[v] = !w[v]; initV[v] = true; } else { if(type[v] == "AND" || type[v] == "NAND") w[v] &= w[u]; else if(type[v] == "OR" || type[v] == "NOR") w[v] |= w[u]; else if(type[v] == "XOR") w[v] ^= w[u]; } if(temp_inDegree[v] == 0) { if(type[v] == "NAND" || type[v] == "NOR") w[v] = !w[v]; q.push(v); } } } } int main(){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int q,m,n;//q表示q个问题,整个电路m个输入,器件数为n cin>>q; while(q--){ //初始化 for(int i=0;i<MAXV;i++){ for(auto it = G[i].begin();it!=G[i].end();){ it = G[i].erase(it); }//清空邻接表,准备处理下一个问题 } memset(inDegree, 0, sizeof(inDegree)); fill(initV, initV + MAXV, false); for(int i = 0;i < MAXV;i++) { type[i].clear(); } for(int i = 0;i < 10005;i++) { for(vector<int>::iterator j = test_in[i].begin();j != test_in[i].end();) { j = test_in[i].erase(j); } } for(int i = 0;i < 10005;i++) { for(vector<int>::iterator j = test_out[i].begin();j != test_out[i].end();) { j = test_out[i].erase(j); } } //初始化完成,开始准备正式处理 cin>>m>>n;//输入个数,器件个数 for(int num = m;num < n + m;num++)//从m开始进行编号 { string FUNC;//器件描述 int k; cin>>FUNC; type[num] = FUNC; cin>>k;//对应几个接口相连接 for(int i = 0;i < k;i++) { string L; cin>>L; int startPoint = atoi(L.substr(1, L.length() - 1).c_str()) - 1;//计算起始点编号 if(L[0] != 'I') {//如果是输出点,则加上输入点的偏移 startPoint += m; } G[startPoint].push_back(Node(num));//构造图 inDegree[num]++;//计算入度 } } int s;//运算次数 cin>>s; for(int i = 0;i < s;i++) {//输入数据 for(int j = 0;j < m;j++) { int input; cin>>input; test_in[i].push_back(input); } } for(int i = 0;i < s;i++)//存入需要输出的数据的位置 {//输出数据 int out_num; cin>>out_num; while(out_num--) { int output; cin>>output; output = output + m - 1; test_out[i].push_back(output); } } if(topologicalSort(m, n) == false) {//有环 cout<<"LOOP"<<endl; } else{ for(int i = 0;i < s;i++)//对应的s次运算 { memset(w, 0, sizeof(w)); fill(initV, initV + MAXV, false); for(int j = 0;j < test_in[i].size();j++) {//给初始输入点赋值 w[j] = test_in[i][j]; } //计算点权 calculate(m, n); for(int j = 0; j < test_out[i].size();j++) { if(j != 0) cout<<" "; cout<<w[test_out[i][j]]; } cout<<endl; } } } return 0; }
标签:点亮,int,inDegree,cin,num,人生,test,out,202009 来源: https://www.cnblogs.com/zmachine/p/14494821.html