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 ...
随机推荐
- ffmpeg推流命令参数记录
列出我们本机的设备:ffmpeg -list_devices true -f dshow -i dummy .\ffmpeg -r 25 -f dshow -s 640*480 -i video=&q ...
- tomcat可以访问默认页面,但是无法访问webapp下的指定项目
tomcat可以访问默认页面,但是无法访问webapp下的指定项目 1.注意下安装tomcat时的默认端口,8005,8009,8080,我这边没有修改,根据需要自行修改,确保tomcat可以启动 ...
- python之路-进程
博客园 首页 新随笔 联系 管理 订阅 随笔- 31 文章- 72 评论- 115 python之路——进程 阅读目录 理论知识 操作系统背景知识 什么是进程 进程调度 进程的并发与并行 ...
- 测试你的浏览器是否支持WebGL(Does My Browser Support WebGL)
测试你的浏览器是否支持WebGL(Does My Browser Support WebGL) 关于WebGL:WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ...
- Azure CLI下载Azure Storage Container内的所有文件
在某些场景下,客户需要把Azure Storage的某一个container内的内容都下载到本地.当然采用PowerShell可以定时的进行下载的动作,但有时客户的环境是Linux或MacOS,这时需 ...
- 【转】 Pro Android学习笔记(五七):Preferences(1):ListPreference
目录(?)[-] 例子1ListPreference小例子 定义一个preferences XML文件 继承PreferenceActivity 用户定制偏好的读取 第一次运行时设置缺省值 设置Cat ...
- vue 给嵌套的iframe子页面传数据 postMessage
Vue组件下嵌套了一个不同域下的子页面,iframe子页面不能直接获取到父页面的数据,即使数据存在localStorage中,子页面一样是获取不到的,所以只好使用postMessage传数据: < ...
- 2440移植内核到uboot上,打印乱码
转载请注明出处:http://blog.csdn.net/qq_26093511/article/details/51851368 可能原因: 1. 修改内核 里的晶振大小 arch\arm\mach ...
- DevExpress 柱状图
通过构造函数,把值传递过来 public XtraInterpreterChartForm(object ds) { InitializeComponent(); datasource = ds; } ...
- [hdu1712]ACboy needs your help分组背包
题意:一共$m$天,$n$门课程,每门课程花费$i$天得到$j$的价值,求最后获得的最大价值 解题关键:分组背包练习,注意循环的顺序不能颠倒 伪代码: $for$ 所有的组$k$ $for{\rm ...