题解 【P2027 bf】

· · 题解

0xff 前言

本题不难,模拟即可。
但是,要注意细节啊!!!
否则,上图便是结果。

0x00 题意

给你一个 BrainF**k 程序和输入,输出这段程序的输出。

0x01 思路

注:由于洛谷的 feature ,本文以 [dollar-sign] 代替 美元符号

由于这道题的输入比较复杂,考虑用指针来输入。

坑点 #1:
程序的结尾和 [dollar-sign] 之间没有空格,但输入的结尾和 [dollar-sign] 之间空格!

就是这玩意儿坑了我 10 多次提交
定义一个指针 \texttt{curr},指向输入数组的开头。
然后一直读入,直到 \texttt{*curr} = [dollar-sign]
然后,令 \texttt{*curr} \gets 0 即可。

读入 \texttt{input} 类似,不过要注意:最后还要\texttt{*(input-1)} \gets 0

然后就是模拟啦!

对于 [ ,跳到与它匹配的 ] 。
注意,不是最近的 ] !
例:++[>++[-]<-]
那怎么匹配呢?

[ 与 ] 类似,在此不再详述。

0x02 代码

#include <cstdio>
#define fo(i_,j_,k_) for(int i_=j_;i_<=k_;++i_)
#define fr(i_,j_,k_) for(int i_=j_;i_>=k_;--i_)
#define It(type_) type_::iterator
#define rg register
#define rtn return
#define il inline

typedef long long ll;
char memory[30005],*ptr;
char cmd[300005],input_[300005],*curr,*input;

int main()
{
    curr = cmd;
    while((*curr = getchar()) && *curr != '$') ++curr;
    *curr = 0;
    getchar(); 

    input = input_; 
    while((*input = getchar())&& *input != '$') ++input;
    *input = 0;
    *(input-1) = 0;

    curr = cmd;
    input = input_;
    ptr = memory;

//  printf("%s,%s.\n",cmd,input); 

    while(*curr != '\0')
    {
        switch(*curr)
        {
            case '<': -- ptr;break;
            case '>': ++ ptr;break;
            case '+': ++ *ptr; break;
            case '-': -- *ptr; break;
            case '.': putchar(*ptr);break;
            case ',':
                *ptr = (*input == '\0')? -1 : *input;
                if(*input != '\0') ++input;
                break;
            case '[':
                if(*ptr == 0)
                {
                    ++curr;
                    int cnt = 0;
                    while(!(*curr == ']' && cnt == 0))
                    {
                        if(*curr == '[') ++cnt;
                        if(*curr == ']') --cnt;
                        ++curr;
                    }
                }
                break;
            case ']':
                --curr;
                int cnt = 0;
                while(!(cnt == 0 && *curr == '['))
                {
                    if(*curr == ']') ++ cnt; 
                    if(*curr == '[') -- cnt; 
                    --curr;
                }   
                --curr;
                break;
        }
        ++curr;
    }
    rtn 0;
}