菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
334
0

202009-3(点亮数字人生)

原创
05/13 14:22
阅读数 83650

注意将题抽象成一个图的形式,同时注意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;
} 

 

相关热门文章

发表评论

0/200
334 点赞
0 评论
收藏