此题太露骨了,叫 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;
}
因篇幅问题不能全部显示,请点此查看更多更全内容