UVA11956题解

· · 题解

题面

题目传送门

(话说这题名真的不会取个文明点的吗)

题目大意:

你的好损友买了一个可以编程的灯,这个灯的程序的代码里面有一个长度为 100 的循环数组和一个指向这个数组的某个位置的指针,数组中每个值也是每 256 个数循环,也就是说如果当前的值为 255 加一则变成 0。这种语言的操作方式有五种:> 表示将指针往右移一格;< 表示将指针往左移一格;+ 表示把指针指向位置的数加一;- 表示把指针指向位置的数减一;. 表示将指针指向的位置的数读出来。现在给定 T 组指令,求每组指令过后数组每个数的 16 进制并严格按两格宽度输出。

思路

这道题属于中级模拟题,适合一些熟练能写出模拟题的人。在题目中并没有说明第五个指令的用途,所以我们可以暂时不管。我们知道,char 类型的范围是 [-128,127],而 unsigned char 的范围刚好就是 [0,255],所以我们用 unsigned char 储存每个数,不用判断小于 0 或大于 255 的情况。指针还是老实的模拟,加上判断是否超出范围。接下来是输出问题。16 进制?两格宽度?我们可以第一个想到 printf%02X,也就是大写 16 进制并保留两格宽度。

代码

#include<bits/stdc++.h>
using namespace std;
unsigned char ans[105];//循环数组
int now,T;//指针位置和数据组数
string s;//操作字符串
int main(){
    cin>>T;
    for(int i=1;i<=T;i++){
        memset(ans,0,sizeof(ans));
        now=1;
        cin>>s;
        for(int j=0;j<s.size();j++){//模拟
            if(s[j]=='+')
                ans[now]++;
            if(s[j]=='-')
                ans[now]--;
            if(s[j]=='>'&&++now>100)//这里用了一个巧妙的方法:如果第一个条件成立,now就会执行加一,再来判断是否大于100,省了很多行
                now=1;
            if(s[j]=='<'&&--now<1)
                now=100;
        }
        printf("Case %d: ",i);
        for(int j=1;j<100;j++)
            printf("%02X ",ans[j]);
        printf("%02X\n",ans[100]);//UVA输出末尾不能有空格就很离谱
    }
    return 0;
}