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-------+
//////////////////////////////////////////////////////////////////////////
// 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的更多相关文章
- POJ题目排序的Java程序
POJ 排序的思想就是根据选取范围的题目的totalSubmittedNumber和totalAcceptedNumber计算一个avgAcceptRate. 每一道题都有一个value,value ...
- POJ题目细究
acm之pku题目分类 对ACM有兴趣的同学们可以看看 DP: 1011 NTA 简单题 1013 Great Equipment 简单题 102 ...
- PHP foreach 遍历数组是打印出相同的数据
https://www.toptal.com/php/10-most-common-mistakes-php-programmers-make PHP makes it relatively easy ...
- 【转】php容易犯错的10个地方
原文地址: http://www.toptal.com/php/10-most-common-mistakes-php-programmers-make 译文地址:http://codecloud.n ...
- 【转】POJ百道水题列表
以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight ...
- Tree - Information Theory
This will be a series of post about Tree model and relevant ensemble method, including but not limit ...
- DeepLearning - Forard & Backward Propogation
In the previous post I go through basic 1-layer Neural Network with sigmoid activation function, inc ...
- QDialog在hide()之后,就被销毁的原因
一路跟踪源码,关键就是这两句: int QDialog::exec() { Q_D(QDialog); if (d->eventLoop) { qWarning("QDialog::e ...
- Follow me to learn what is repository pattern
Introduction Creating a generic repository pattern in an mvc application with entity framework is th ...
随机推荐
- 启用Linux云平台oracle数据库实口令复杂性函数:PASSWORD_VERIFY_FUNCTION=NULL
第一步:采用putty.exe登录数据库服务器. 输入IP后点击“Open”按钮: 第二步:登录对应的数据库实例. 执行:# su – oracle 查找:$ps -ef | grep pmon 找到 ...
- UE3优化
转自:http://www.cnblogs.com/NEOCSL/p/3320510.html 优化问题有很多内容可讲,涉及林林总总.今天我总结一下优化注意的地方. 1.从AnimTree和Skele ...
- SpringMvc之参数绑定注解详解之一
引言: 前段时间项目中用到了REST风格来开发程序,但是当用POST.PUT模式提交数据时,发现服务器端接受不到提交的数据(服务器端参数绑定没有加 任何注解),查看了提交方式为application/ ...
- j++与++j
(j++)+(++j)+(++j) 核心部分汇编代码 执行顺序j原始值为5,存放在栈的ebp-4中;q无初始值,存放在栈的ebp-8中先执行一次j自增赋值++j ;j=6执行第一个加法运算;值存放在C ...
- [nowCoder] 两个长度相同有序数组的中位数
给定两个有序数组arr1和arr2,两个数组长度都为N,求两个数组中所有数的上中位数.例如:arr1 = {1,2,3,4};arr2 = {3,4,5,6};一共8个数则上中位数是第4个数,所以返回 ...
- Linux Screen超简明教程
1.安装Screen 大多数情况下,系统已经安装好了screen.如果没有,可以用下面的命令来安装: CentOS系统中执行:yum install screen Debian/Ubuntu系统执行: ...
- 关于overflow:hidden (转)
关于overflow:hidden (本文只针对hidden这个值的用处进行阐述) 关于overflow:hidden;很多人都知道他是溢出隐藏的一个属性,但是并不是很多人知道它的一些神奇的地方! ...
- Servlet处理流程分析
---------------siwuxie095 Tomcat 处理客户端请求的方式: Tomcat 既是一个 Servlet ...
- 9、scala函数式编程-集合操作
一.集合操作1 1.Scala的集合体系结构 // Scala中的集合体系主要包括:Iterable.Seq.Set.Map.其中Iterable是所有集合trait的根trai.这个结构与Java的 ...
- 8、泛型程序设计与c++标准模板库2.5容器适配器
容器适配器是用来扩展7中基本容器的,是修改和调整其他类接口的类.他们不提供存放数据的实际数据结构的实现方法,而且容器适配器也不支持迭代器. 1.标准栈容器 使用STL中的标准栈为程序员提供了一层附加的 ...