提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
题目链接
提示:以下是本篇文章正文内容,下面案例可供参考
一、解答
1.思路
(1)用邻接表存储图,构造节点类,在构造方法中获得他的父亲节点
(2)进行拓扑排序,由于每次进入队列的节点均入度为零(即他的输出全部已知),则可以直接计算,将每个节点在每次输入下的输出值保存在一个二维数组。
(3)若拓扑排序没有检测到环路,则正确输出。
2.代码示例
60分代码如下:
#define _CRT_SECURE_NO_WARNINGS 1;
#include<iostream>
#include<string>
#include<string.h>
#include<cstring>
using namespace std;
const int k_max = 7;
const int n_max = 510;
const int s_max = 10005;
const int in_max = k_max * n_max;
int find_symbol(string str,int st,char ch) {
for (int i = st; i <= str.length() - 1; i++) {
if (str[i] == ch) {
return i;
}
}
return str.length();
}
string get_str(string str,int st,int en) {
string res;
for (int i = st; i < en; i++) {
res += str[i];
}
return res;
}
class node {
public:
string oprt;
int inputnum;
string input[k_max];
int parent[k_max];
int p_num=0;
node(string info) {
int i = 0;
int j = find_symbol(info, i, ' ');
oprt = get_str(info, i, j);
i = j + 1;
j = find_symbol(info, i, ' ');
inputnum = get_str(info, i, j)[0] - '0';
for (int t = 0; t < inputnum; t++) {
i = j + 1;
j = find_symbol(info, i, ' ');
input[t] = get_str(info, i, j);
if (input[t][0] == 'O') {
int num = 0;
for (int r = 1; r < input[t].length(); r++) {
num *= 10;
num += input[t][r] - '0';
}
parent[p_num++] = num;
}
}
}
node() {
}
};
int total, e[in_max], h[n_max], ne[in_max], d[in_max];
int total_input[s_max][in_max], out_value[s_max][n_max];
int s;
node nod[n_max];
void insert(int i) {
for (int j = 0; j < nod[i].p_num; j++) {
int par = nod[i].parent[j];
e[total] = i;
ne[total] = h[par];
h[par] = total;
d[i]++;
total++;
}
}
void get_res(int out) {
for (int j = 0; j < s; j++) {
int res = -2, pi = 0;
for (int i = 0; i < nod[out].inputnum; i++) {
string in = nod[out].input[i];
int temp;
if (in[0] = 'I') {
int num = 0;
for (int r = 1; r < in.length(); r++) {
num *= 10;
num += in[r] - '0';
}
temp = total_input[j][num];
}
else {
int num = nod[out].parent[pi++];
temp = out_value[j][num];
}
if (res == -2) {
if (nod[out].oprt != "NOT") {
res = temp;
}
else {
res = -1 * temp + 1;
}
}
else {
if (nod[out].oprt == "AND" || nod[out].oprt == "NAND") {
res = res & temp;
}
else if (nod[out].oprt == "OR" || nod[out].oprt == "NOR") {
res = res | temp;
}
else if(nod[out].oprt=="XOR"){
res = res ^ temp;
}
}
}
if (nod[out].oprt == "NAND" || nod[out].oprt == "NOR") {
res = -1 * res + 1;
}
out_value[j][out] = res;
}
}
bool topsort(int n) {
int q[in_max], qh = 0, qt = -1;
for (int i = 1; i <= n; i++) {
if (d[i] == 0) {
q[++qt] = i;
get_res(i);
}
}
while (qh <= qt) {
int x = q[qh++];
for (int j = h[x]; j != -1; j = ne[j]) {
d[e[j]]--;
if (d[e[j]] == 0) {
q[++qt] = e[j];
get_res(e[j]);
}
}
}
return qt == n - 1;
}
int main() {
int q;
scanf("%d", &q);
for (int i = 0; i < q; i++) {
total = 0;
memset(h, -1, sizeof h);
memset(d, 0, sizeof d);
int m, n;
scanf("%d %d", &m, &n);
getchar();
for (int j = 1; j <= n; j++) {
string info;
getline(cin, info);
node n1(info);
nod[j] = n1;
insert(j);
}
scanf("%d", &s);
for (int j = 0; j < s; j++) {
for (int t = 1; t <= m; t++) {
scanf("%d", &total_input[j][t]);
}
}
if (!topsort(n)) {
printf("LOOP\n");
continue;
}
else {
for (int j = 0; j < s; j++) {
int si;
scanf("%d", &si);
for (int t = 0; t < si; t++) {
int o;
scanf("%d", &o);
printf("%d ", out_value[j][o]);
}
printf("\n");
}
}
}
}
总结
在时间复杂度还可以优化,比如掌握父亲节点,判断回路等等,第六个测试点之后的样例是运行错误,猜测为数组大小不够,希望大佬可以对我的代码加以改进。