题目来源: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-------+
 //////////////////////////////////////////////////////////////////////////
// POJ1048 Follow My Logic
// Memory: 180K Time: 0MS
// Language: C++ Result: Accepted
////////////////////////////////////////////////////////////////////////// #include <iostream>
#include <cstdio> using namespace std; char circuit[][];
int h;
int x, y; enum DIR {
LEFT, UP, RIGHT, DOWN
}; struct Node {
int type; //0-25表示对应输入状态的序号(A-Z); -2 and; -3 or; -4 not.
int left_child;
int right_child;
}; Node tree[];
int tree_len; char input[]; bool ReadCircuit() {
memset(circuit, , sizeof(circuit));
if (!gets(circuit[])) return false;
h = ;
while (gets(circuit[h++])) {
if (circuit[h - ][] == '*') {
--h;
break;
}
}
return true;
} void FindOutput() {
for (int i = ; i < h; ++i) {
for (int j = ; j < ; ++j) {
if (circuit[i][j] == '\0') break;
if (circuit[i][j] == '?') {
x = i;
y = j;
return;
}
}
}
} void ConstructTree(int x, int y, int node_id, DIR dir) {
switch (circuit[x][y]) {
case '?':
if (circuit[x][y - ] == '-') ConstructTree(x, y - , node_id, LEFT);
else if (circuit[x][y + ] == '-') ConstructTree(x, y + , node_id, RIGHT);
else if (circuit[x - ][y] == '|') ConstructTree(x - , y, node_id, UP);
else if (circuit[x + ][y] == '|') ConstructTree(x + , y, node_id, DOWN);
else ConstructTree(x, y - , node_id, LEFT);
break;
case ')':
tree[node_id].type = -; //and
tree[node_id].left_child = ++tree_len;
tree[node_id].right_child = ++tree_len;
ConstructTree(x - , y - , tree[node_id].left_child, LEFT);
ConstructTree(x + , y - , tree[node_id].right_child, LEFT);
break;
case '>':
tree[node_id].type = -; //or
tree[node_id].left_child = ++tree_len;
tree[node_id].right_child = ++tree_len;
ConstructTree(x - , y - , tree[node_id].left_child, LEFT);
ConstructTree(x + , y - , tree[node_id].right_child, LEFT);
break;
case 'o':
tree[node_id].type = -; //not
tree[node_id].left_child = ++tree_len;
tree[node_id].right_child = -;
if (circuit[x][y - ] == ')' || circuit[x][y - ] == '>')
ConstructTree(x, y - , tree[node_id].left_child, LEFT);
else if (circuit[x][y - ] == '-' && dir != RIGHT)
ConstructTree(x, y - , tree[node_id].left_child, LEFT);
else if (circuit[x][y + ] == '-' && dir != LEFT)
ConstructTree(x, y - , tree[node_id].left_child, RIGHT);
else if (circuit[x - ][y] == '|' && dir != DOWN)
ConstructTree(x - , y, tree[node_id].left_child, UP);
else ConstructTree(x + , y, tree[node_id].left_child, DOWN);
break;
case '+':
if (dir == UP || dir == DOWN) {
if (circuit[x][y - ] == '-') ConstructTree(x, y - , node_id, LEFT);
else ConstructTree(x, y + , node_id, RIGHT);
} else {
if (circuit[x - ][y] == '|')ConstructTree(x - , y, node_id, UP);
else ConstructTree(x + , y, node_id, DOWN);
}
break;
case '-':
if (dir == LEFT) ConstructTree(x, y - , node_id, LEFT);
else ConstructTree(x, y + , node_id, RIGHT);
break;
case '|':
if (dir == UP) ConstructTree(x - , y, node_id, UP);
else ConstructTree(x + , y, node_id, DOWN);
break;
default:
tree[node_id].left_child = -;
tree[node_id].right_child = -;
tree[node_id].type = circuit[x][y] - 'A';
}
} bool GetInput() {
scanf("%s", input);
if (input[] == '*') return false;
return true;
} int GetOutput(int i) {
switch (tree[i].type) {
case -: //and
return GetOutput(tree[i].left_child) && GetOutput(tree[i].right_child);
case -: //or
return GetOutput(tree[i].left_child) || GetOutput(tree[i].right_child);
case -: //not
return !GetOutput(tree[i].left_child);
default:
return input[tree[i].type] - '';
}
} int main(){
while (ReadCircuit()){
FindOutput();
tree_len = ;
ConstructTree(x, y, , LEFT);
while (GetInput()) {
printf("%d\n", GetOutput());
}
printf("\n");
}
return ;
}

POJ1048 Follow My Logic的更多相关文章

  1. POJ题目排序的Java程序

    POJ 排序的思想就是根据选取范围的题目的totalSubmittedNumber和totalAcceptedNumber计算一个avgAcceptRate. 每一道题都有一个value,value ...

  2. POJ题目细究

    acm之pku题目分类 对ACM有兴趣的同学们可以看看 DP:  1011   NTA                 简单题  1013   Great Equipment     简单题  102 ...

  3. PHP foreach 遍历数组是打印出相同的数据

    https://www.toptal.com/php/10-most-common-mistakes-php-programmers-make PHP makes it relatively easy ...

  4. 【转】php容易犯错的10个地方

    原文地址: http://www.toptal.com/php/10-most-common-mistakes-php-programmers-make 译文地址:http://codecloud.n ...

  5. 【转】POJ百道水题列表

    以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight ...

  6. Tree - Information Theory

    This will be a series of post about Tree model and relevant ensemble method, including but not limit ...

  7. DeepLearning - Forard & Backward Propogation

    In the previous post I go through basic 1-layer Neural Network with sigmoid activation function, inc ...

  8. QDialog在hide()之后,就被销毁的原因

    一路跟踪源码,关键就是这两句: int QDialog::exec() { Q_D(QDialog); if (d->eventLoop) { qWarning("QDialog::e ...

  9. Follow me to learn what is repository pattern

    Introduction Creating a generic repository pattern in an mvc application with entity framework is th ...

随机推荐

  1. 【leetcode刷题笔记】Remove Duplicates from Sorted Array II

    Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For exampl ...

  2. 【二叉查找树】03验证是否为二叉查找树【Validate Binary Search Tree】

    本质上是递归遍历左右后在与根节点做判断,本质上是后序遍历 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...

  3. FFmpeg基础知识之————H264编码profile & level控制

    H.264有四种画质级别,分别是baseline, extended, main, high: 1.Baseline Profile:基本画质.支持I/P 帧,只支持无交错(Progressive)和 ...

  4. 使用WindowsAPI获取录音音频的方法

    这篇文章主要介绍了使用WindowsAPI获取录音音频的方法,非常实用的功能,需要的朋友可以参考下 本文实例介绍了使用winmm.h进行音频流的获取的方法,具体步骤如下: 一.首先需要包含以下引用对象 ...

  5. A唐纳德先生和假骰子(华师网络赛)

    Time limit per test: 1.0 seconds Memory limit: 256 megabytes 在进行某些桌游,例如 UNO 或者麻将的时候,常常会需要随机决定从谁开始.骰子 ...

  6. 使用NSURLProtocol和NSURLSession拦截UIWebView的HTTP请求(包括ajax请求)

    问题:服务器端有一个网站需要AD认证,整站都开了Basic认证,包括图片,CSS等资源,我在HTTP请求头里面添加认证所需的用户名和密码,传递到服务器端可以认证通过.我在UIWebView的shoul ...

  7. Cloudera安装要点

    C方式是完全离线方式 https://www.cloudera.com/documentation/enterprise/5-10-x/topics/cm_ig_installing_configur ...

  8. bzoj 2648 SJY摆棋子 —— K-D树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648 学习资料:https://blog.csdn.net/zhl30041839/arti ...

  9. Netty组件

    一.Channel.EventLoop 和ChannelFuture 这些类合在一起,可以被认为是Netty 网络抽象的代表: Channel—Socket: EventLoop—控制流.多线程处理. ...

  10. JavaScript-Tool:jquery.cookie.js

    ylbtech-JavaScript-Tool:jquery.cookie.js 1.返回顶部 1.jquery.cookie.js /*! * jQuery Cookie Plugin v1.4.0 ...