Follow My Logic(递归,模拟)

题目大意:

  给定一个逻辑电路,求其逻辑输出。电路含一个或多个输入,以及一些双输入的与门/或门组成。电路图以下面形式的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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值