CSP 202009-3 点亮数字人生

谁来点亮鼠鼠的人生啊,最近属于是卷也卷不动,躺也躺不平。

果然菜是原罪。

通过拓扑排序判断有向环学到了

emmm,代码太长啦,及其不优雅

一个bug调了1个小时,乐

#include <bits/stdc++.h>
using namespace std;
int Q,M,N,S;
struct Part{
    int func;
    set<int> input;//直接来自哪个输入
    vector<int> res;//存放有哪些东西
};
/*
 * NOT 0
 * AND 1
 * OR 2
 * XOR 3
 * NAND 4
 * NOR 5
 */
void put(int id, string func, vector<Part>& pa) {
    if (func == "NOT") {
        pa[id].func = 0;
    } else if (func == "AND") {
        pa[id].func = 1;
    } else if (func == "OR") {
        pa[id].func = 2;
    } else if (func == "XOR") {
        pa[id].func = 3;
    } else if (func == "NAND") {
        pa[id].func = 4;
    } else {
        pa[id].func = 5;
    }
}
bool check(vector<vector<int>>& g) {
    vector<int> inc(N + 1, 0);
    queue<int>que;
    for (int i = 1; i <= N; i++) {
        for (auto& t : g[i]) {
            inc[t]++;
        }
    }
    for (int i = 1; i <= N; i++) {
        if (inc[i] == 0) {que.push(i);}
    }
    int n = 0;
    while (!que.empty()) {
        auto cur = que.front(); que.pop();
        n++;
        for (auto& t: g[cur]) {
            if (--inc[t] == 0) {
                que.push(t);
            }
        }
    }
    return N == n;
}
int calRes(int id, vector<Part>& parts) {
    int ret = 0;
    if (parts[id].func == 0) {
        ret = (!parts[id].res[0]);
    } else if (parts[id].func == 1) {
        ret = 1;
        for (auto& re : parts[id].res) {
            ret &= re;
        }
    } else if (parts[id].func == 2) {
        ret = 0;
        for (auto& re : parts[id].res) {
            ret |= re;
        }
    } else if (parts[id].func == 3) {
        ret = 0;
        for (auto& re : parts[id].res) {
            ret ^= re;
        }
    } else if (parts[id].func == 4) {
        ret = 1;
        for (auto& re : parts[id].res) {
            ret &= re;
        }
        ret = !ret;
    } else {
        ret = 0;
        for (auto& re : parts[id].res) {
            ret |= re;
        }
        ret = !ret;
    }
    return ret;
}
void calc(vector<vector<int>>& g,vector<Part> parts,vector<int> inputs, vector<int> t_check) {
    map<int,int> output;
    queue<int>que;
    vector<int> inc(N + 1, 0);
    vector<int> topoOrder;
    for (int i = 1; i <= N; i++) {
        for (auto& t : g[i]) {
            inc[t]++;
        }
    }
    for (int i = 1; i <= N; i++) {
        if (inc[i] == 0) {que.push(i);}
    }
    while (!que.empty()) {
        auto cur = que.front(); que.pop();
        topoOrder.push_back(cur);
        for (auto& t : g[cur]) {
            inc[t]--;
            if (inc[t] == 0) {
                que.push(t);
            }
        }
    }

    for (auto& cur : topoOrder) {
        vector<int> to_add;
        for (auto& id : parts[cur].input) {
            to_add.push_back(inputs[id - 1]);
        }

        for (auto ele: to_add) {
            parts[cur].res.push_back(ele);
        }
        int res = calRes(cur,parts);
        output[cur] = res;
        for (auto& t: g[cur]) {
            parts[t].res.push_back(res);
        }
    }
    for (auto& id : t_check) {
        cout << output[id] << ' ';
    }
    cout << '\n';
}
void solve() {
    vector<vector<int>> g(N + 1);//N个器件
    vector<Part> parts(N + 1);//N个器件
    for (int i = 0; i < N; i++) {//描述每个器件
        string func; cin >> func;//器件功能
        int k; cin >> k; //k个输入
        put(i + 1, func, parts);
        for (int j = 0; j < k; j++) {
            string inp; cin >> inp;
            int tmp = atoi(inp.substr(1).c_str());
            if (inp[0] == 'I') {
                parts[i + 1].input.insert(tmp);
            } else {
                g[tmp].push_back(i + 1);
                //parts[i + 1].inp_from.insert(tmp);
            }
        }
    }
    bool flg = check(g);
    cin >> S;
    vector<vector<int>> inputs(S);
    vector<vector<int>> t_check(S);
    for (int i = 0; i < S; i++) {
        for (int j = 0; j < M; j++) {
            int t; cin >> t;
            inputs[i].push_back(t);
        }
    }
    for (int i = 0; i < S; i++) {
        int s; cin >> s;
        for (int j = 0; j < s; j++) {
            int t;cin >> t;
            t_check[i].push_back(t);
        }
    }
    if (!flg) {cout << "LOOP\n"; return;}
    for (int i = 0; i < S; i++) {
        calc(g,parts,inputs[i],t_check[i]);
    }
}
int main() {
    std::ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> Q;
    while (Q--) {
        cin >> M >> N;
        solve();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值