• POJ1048 Follow My Logic


    题目来源: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] == '') break;
     48             if (circuit[i][j] == '?') {
     49                 x = i;
     50                 y = j;
     51                 return;
     52             }
     53         }
     54     }
     55 }
     56 
     57 void ConstructTree(int x, int y, int node_id, DIR dir) {
     58     switch (circuit[x][y]) {
     59         case '?':
     60             if (circuit[x][y - 1] == '-') ConstructTree(x, y - 2, node_id, LEFT);
     61             else if (circuit[x][y + 1] == '-') ConstructTree(x, y + 2, node_id, RIGHT);
     62             else if (circuit[x - 1][y] == '|') ConstructTree(x - 2, y, node_id, UP);
     63             else if (circuit[x + 1][y] == '|') ConstructTree(x + 2, y, node_id, DOWN);
     64             else ConstructTree(x, y - 1, node_id, LEFT);
     65             break;
     66         case ')':
     67             tree[node_id].type = -2;    //and
     68             tree[node_id].left_child = ++tree_len;
     69             tree[node_id].right_child = ++tree_len;
     70             ConstructTree(x - 1, y - 3, tree[node_id].left_child, LEFT);
     71             ConstructTree(x + 1, y - 3, tree[node_id].right_child, LEFT);
     72             break;
     73         case '>':
     74             tree[node_id].type = -3;    //or
     75             tree[node_id].left_child = ++tree_len;
     76             tree[node_id].right_child = ++tree_len;
     77             ConstructTree(x - 1, y - 3, tree[node_id].left_child, LEFT);
     78             ConstructTree(x + 1, y - 3, tree[node_id].right_child, LEFT);
     79             break;
     80         case 'o':
     81             tree[node_id].type = -4;    //not
     82             tree[node_id].left_child = ++tree_len;
     83             tree[node_id].right_child = -1;
     84             if (circuit[x][y - 1] == ')' || circuit[x][y - 1] == '>') 
     85                 ConstructTree(x, y - 1, tree[node_id].left_child, LEFT);
     86             else if (circuit[x][y - 1] == '-' && dir != RIGHT) 
     87                 ConstructTree(x, y - 2, tree[node_id].left_child, LEFT);
     88             else if (circuit[x][y + 1] == '-' && dir != LEFT) 
     89                 ConstructTree(x, y - 2, tree[node_id].left_child, RIGHT);
     90             else if (circuit[x - 1][y] == '|' && dir != DOWN) 
     91                 ConstructTree(x - 2, y, tree[node_id].left_child, UP);
     92             else ConstructTree(x + 2, y, tree[node_id].left_child, DOWN);
     93             break;
     94         case '+':
     95             if (dir == UP || dir == DOWN) {
     96                 if (circuit[x][y - 1] == '-') ConstructTree(x, y - 2, node_id, LEFT);
     97                 else ConstructTree(x, y + 2, node_id, RIGHT);
     98             } else {
     99                 if (circuit[x - 1][y] == '|')ConstructTree(x - 2, y, node_id, UP);
    100                 else ConstructTree(x + 2, y, node_id, DOWN);
    101             }
    102             break;
    103         case '-':
    104             if (dir == LEFT) ConstructTree(x, y - 1, node_id, LEFT);
    105             else ConstructTree(x, y + 1, node_id, RIGHT);
    106             break;
    107         case '|':
    108             if (dir == UP) ConstructTree(x - 1, y, node_id, UP);
    109             else ConstructTree(x + 1, y, node_id, DOWN);
    110             break;
    111         default:
    112             tree[node_id].left_child = -1;
    113             tree[node_id].right_child = -1;
    114             tree[node_id].type = circuit[x][y] - 'A';
    115     }
    116 }
    117 
    118 bool GetInput() {
    119     scanf("%s", input);
    120     if (input[0] == '*') return false;
    121     return true;
    122 }
    123 
    124 int GetOutput(int i) {
    125     switch (tree[i].type) {
    126         case -2:    //and
    127             return GetOutput(tree[i].left_child) && GetOutput(tree[i].right_child);
    128         case -3:    //or
    129             return GetOutput(tree[i].left_child) || GetOutput(tree[i].right_child);
    130         case -4:    //not
    131             return !GetOutput(tree[i].left_child);
    132         default:
    133             return input[tree[i].type] - '0';
    134     }
    135 }
    136 
    137 int main(){
    138     while (ReadCircuit()){
    139         FindOutput();
    140         tree_len = 0;
    141         ConstructTree(x, y, 0, LEFT);
    142         while (GetInput()) {
    143             printf("%d
    ", GetOutput(0));
    144         }
    145         printf("
    ");
    146     }
    147     return 0;
    148 }
    View Code
  • 相关阅读:
    Python在函数中使用*和**接收元组和列表
    nvidia-smi实时刷新并高亮显示状态
    linux docker
    linux Vue+nginx+django 实现前后端分离
    linux mysql 主从复制
    linux redis
    linux mysql主从复制
    linux python虚拟环境 相关的
    linux dns
    2 linux vim sudo 文件权限
  • 原文地址:https://www.cnblogs.com/dengeven/p/3248948.html
Copyright © 2020-2023  润新知