题目大意:
给定一个逻辑电路,求其逻辑输出。电路含一个或多个输入,以及一些双输入的与门/或门组成。电路图以下面形式的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. 文件中至少含有一个电路图和一组输入状态。
输出:程序输出每个电路图对每个输入状态的逻辑输出值。每个输入状态单独一行,每个电路图的输出之间用空格隔开。
先找到“?",然后一步一步递归计算。
电路有如下几种情况:
"-":可能向左也可能向右
"|":可能向上也可能向下 ">"或")":向右,递归时就是向左走
"+":总的来说2种,先"|"和先"-";
"o":根据规则1,6,只可能是-o: : >o- : )o-
#include<stdio.h>
#include<string.h>
#define M 105
char cir[M][M];
char in[M];
int outx,outy;
void getout(int n)
{
for (int i = 0; i < n; i++)
{
int len = strlen(cir[i]);
for (int j = 0; j < len; j++)
if (cir[i][j] == '?')
{
outx = i;
outy = j;
return;
}
}
}
int getans(int x, int y, char dir)
{
switch (cir[x][y])
{
case '?':
if (x - 1 >= 0 && cir[x - 1][y] == '|')
return getans(x - 1, y, 'u');
else if (x + 1 < 100 && cir[x + 1][y] == '|')
return getans(x + 1, y, 'd');
else if (y - 1 >= 0 && cir[x][y - 1] == '-')
return getans(x, y - 1, 'l');
else
return getans(x, y + 1, 'r');
break;
case '|':
if (dir == 'u')
return getans(x - 1, y, dir);
else
return getans(x + 1, y, dir);
break;
case '-':
if (dir == 'l')
return getans(x, y - 1, dir);
else
return getans(x, y + 1, dir);
break;
case '+':
if (dir == 'l' || dir == 'r')
{
if (x - 1 >= 0 && cir[x - 1][y] == '|')
return getans(x - 1, y, 'u');
else
return getans(x + 1, y, 'd');
}
else
{
if (y - 1 >= 0 && cir[x][y - 1] == '-')
return getans(x, y - 1, 'l');
else
return getans(x, y + 1, 'r');
}
break;
case ')':
return getans(x - 1, y - 3, 'l') & getans(x + 1, y - 3, 'l');
break;
case '>':
return getans(x - 1, y - 3, 'l') | getans(x + 1, y - 3, 'l');
break;
case 'o':
return !getans(x, y - 1, 'l');
break;
default:
return in[cir[x][y] - 'A'] - '0';
}
}
int main()
{
memset(cir, 0, sizeof(cir));
while (gets(cir[0]) && cir[0][0] != EOF)
{
int n = 1;
while (gets(cir[n]) && strcmp(cir[n], "*"))
n++;
getout(n);
while (gets(in) && strcmp(in, "*"))
printf("%d\n", getans(outx, outy, 'm'));
memset(cir, 0, sizeof(cir));
puts("");
}
return 0;
}