题目来源:http://poj.org/problem?id=1048
题目大意:
给定一个逻辑电路,求其逻辑输出。电路含一个或多个输入,以及一些双输入的与门/或门组成。电路图以下面形式的ASCII码图给出。 电路中,路径由横线,纵线和折点组成,'-'和'|'表示横线和纵线,'+'表示折点。输入由大写字母A到Z表示,输出由'?'表示。与门和或门的表示方法如图所示,而且它们的朝向时钟与图示一致(不会反向或成竖直方向)。门的输入和输出可以被取“非”,用小写的'o'表示。下图最右为一个简单但完整的电路。
: : -: -o: A-o:
: ) : > : )- : )o- : )o-?
:/ :/ -:/ --:/ B--:/
AND gate OR gate Gate with inputs An inverted top input Two logic inputs
and an inverted output and the output
输入:电路遵循以下规则:
1. 电路图的最大尺寸为100*100.
2. 线路始终沿直线,除非遇到折点。折点处,路径转弯90°,折点不会相邻。
3. 所有的线路都不会中途中断。
4. 线路不会相交。
5. 逻辑门始终如上图所示,输入位于左侧,输出位于右侧。
6. “非”只会出现在紧邻逻辑门输入或输出的地方,且前面(紧邻输入时)或后面(紧邻输出时)接有至少一个'-'或'|'.
遇到只含一个'*'的一行时,表示电路图结束,后面为电路图输入状态。每个输入由一行组成,为一个由26个0或1组成的串。第一个数为A的值,第二个为B,以此类推。给定的输入值中电路图里没有用到的应被忽略。"*"表示输入状态结束。
接下来是另一副电路图和新的输入状态,直到遇到end of file. 文件中至少含有一个电路图和一组输入状态。
输出:程序输出每个电路图对每个输入状态的逻辑输出值。每个输入状态单独一行,每个电路图的输出之间用空格隔开。
Sample Input
A---: : )---? B---:/ * 00000000000000000000000000 10000000000000000000000000 01000000000000000000000000 11000000000000000000000000 * A---+ | +---: : >o---: +---:/ : )---? | C--o:/ B---+ * 00000000000000000000000000 11100000000000000000000000 *
Sample Output
0 0 0 1 1 0
首先读入整幅电路图,找到电路图输出的位置,然后递归分析电路图的逻辑结构,构造一颗逻辑树。然后对于每个输入状态根据逻辑树去递归求值即可。但是要注意电路图中线路方向的处理问题,因为图并非一定是规矩的沿从左至方向,线路可能弯折。比如下面的例子:
A-+ | o: : )-? B--:/
A---+ | +---: : >o---: +---:/ : )---? | C--o:/ +---+ | B-------+
1 ////////////////////////////////////////////////////////////////////////// 2 // POJ1048 Follow My Logic 3 // Memory: 180K Time: 0MS 4 // Language: C++ Result: Accepted 5 ////////////////////////////////////////////////////////////////////////// 6 7 #include <iostream> 8 #include <cstdio> 9 10 using namespace std; 11 12 char circuit[105][105]; 13 int h; 14 int x, y; 15 16 enum DIR { 17 LEFT, UP, RIGHT, DOWN 18 }; 19 20 struct Node { 21 int type; //0-25表示对应输入状态的序号(A-Z); -2 and; -3 or; -4 not. 22 int left_child; 23 int right_child; 24 }; 25 26 Node tree[400]; 27 int tree_len; 28 29 char input[27]; 30 31 bool ReadCircuit() { 32 memset(circuit, 0, sizeof(circuit)); 33 if (!gets(circuit[0])) return false; 34 h = 1; 35 while (gets(circuit[h++])) { 36 if (circuit[h - 1][0] == '*') { 37 --h; 38 break; 39 } 40 } 41 return true; 42 } 43 44 void FindOutput() { 45 for (int i = 0; i < h; ++i) { 46 for (int j = 0; j < 100; ++j) { 47 if (circuit[i][j] == '