题目来源: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. ffmpeg推流命令参数记录

    列出我们本机的设备:ffmpeg -list_devices true -f dshow -i dummy .\ffmpeg -r 25 -f dshow -s 640*480 -i video=&q ...

  2. tomcat可以访问默认页面,但是无法访问webapp下的指定项目

     tomcat可以访问默认页面,但是无法访问webapp下的指定项目 1.注意下安装tomcat时的默认端口,8005,8009,8080,我这边没有修改,根据需要自行修改,确保tomcat可以启动 ...

  3. python之路-进程

    博客园 首页 新随笔 联系 管理 订阅 随笔- 31  文章- 72  评论- 115    python之路——进程   阅读目录 理论知识 操作系统背景知识 什么是进程 进程调度 进程的并发与并行 ...

  4. 测试你的浏览器是否支持WebGL(Does My Browser Support WebGL)

    测试你的浏览器是否支持WebGL(Does My Browser Support WebGL) 关于WebGL:WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ...

  5. Azure CLI下载Azure Storage Container内的所有文件

    在某些场景下,客户需要把Azure Storage的某一个container内的内容都下载到本地.当然采用PowerShell可以定时的进行下载的动作,但有时客户的环境是Linux或MacOS,这时需 ...

  6. 【转】 Pro Android学习笔记(五七):Preferences(1):ListPreference

    目录(?)[-] 例子1ListPreference小例子 定义一个preferences XML文件 继承PreferenceActivity 用户定制偏好的读取 第一次运行时设置缺省值 设置Cat ...

  7. vue 给嵌套的iframe子页面传数据 postMessage

    Vue组件下嵌套了一个不同域下的子页面,iframe子页面不能直接获取到父页面的数据,即使数据存在localStorage中,子页面一样是获取不到的,所以只好使用postMessage传数据: < ...

  8. 2440移植内核到uboot上,打印乱码

    转载请注明出处:http://blog.csdn.net/qq_26093511/article/details/51851368 可能原因: 1. 修改内核 里的晶振大小 arch\arm\mach ...

  9. DevExpress 柱状图

    通过构造函数,把值传递过来 public XtraInterpreterChartForm(object ds) { InitializeComponent(); datasource = ds; } ...

  10. [hdu1712]ACboy needs your help分组背包

    题意:一共$m$天,$n$门课程,每门课程花费$i$天得到$j$的价值,求最后获得的最大价值 解题关键:分组背包练习,注意循环的顺序不能颠倒 伪代码: $for$ 所有的组$k$   $for{\rm ...