P2027 bf

此题太露骨了,叫 BrainFu*k。本文中的 dollar 都显示成 ¥。

思路

这道题不难,是道大模拟题关键就在这句话:

字符|意义
<  |指针所指向的内存地址减一。
>  |指针所指向的内存地址加一。
+  |指针所指向的内存里面的数值加一。
-  |指针所指向的内存里面的数值减一。
.  |输出当前指针所指向的内存里面的数值(以字符形式输出)。
,  |将读入缓冲区中的一个字节送入当前指针指向的内存里面。如果读入缓冲区为空则送入-1。
[  |当前指针指向的内存里面的数值不为0时,重复执行与之相匹配的]之间的语句,直到回到[时当前指针指向的内存中的数值为0。
]  |如上。

模拟就完事了!主要难点就在输入这块地方。

实现

第一个 ¥ 之前是运算区,用 code 数组存储,¥ 之后是缓冲区用 yuan 数组存储。数据统一存储在 data 数组中,方括号匹配用类似栈的 stack 数组存储,a 数组用来解决循环问题。

注意:题目中描述:¥ 后面紧跟一个空格(不属于输入缓冲区)。

如果你用纸验算一下可以发现这些运算符具有一下特点(设指针为 n):

字符|意义
<  |n--
>  |n++。
+  |data[n]++。
-  |data[n]--。
.  |cout<<(char)data[n]。
,  |if(yuan[cnt])data[n]=yuan[cnt++];else cout<<-1;
[  |if (!data[n])i = a[i];
]  |if (!data[n])i = a[i];

发现这个规律,题目不就迎刃而解了吗?

代码

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
char code[30010];
int yuan[30010], data[30010], stack[30010], a[30010];
int n, cnt, tot;
int main()
{
    while ((code[tot++] = getchar()) != '$')
        ;
    getchar(); // 输入代码
    code[n - 1] = 0, n = 0;
    while ((yuan[n++] = getchar()) != '$')
        ;
    yuan[n - 2] = 0, n = 0; // 输入缓冲区
    for (int i = 0; code[i]; i++)
        if (code[i] == '<' || code[i] == '>' || code[i] == '+' || code[i] == '-' || code[i] == '.' || code[i] == ',' || code[i] == '[' || code[i] == ']')
            code[n++] = code[i]; // 抹去没用的
    code[n] = 0;
    n = 0;
    for (int i = 0; code[i]; i++) {
        if (code[i] == '[')
            stack[++tot] = i;
        else if (code[i] == ']')
            a[i] = stack[tot--], a[a[i]] = i;
    }
    for (int i = 0; code[i]; i++) {
        switch (code[i]) { // 提到的运算符
        case '<':
            n--;
            break;
        case '>':
            n++;
            break;
        case '-':
            data[n]--;
            break;
        case '+':
            data[n]++;
            break;
        case '.':
            cout << (char)data[n];
            break;
        case ',':
            if (yuan[cnt])
                data[n] = yuan[cnt++];
            else
                data[n] = -1;
            break;
        case '[':
            if (!data[n])
                i = a[i];
            break;
        case ']':
            if (data[n])
                i = a[i];
            break;
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值