Codeforces - 133B - Unary (水题)

Codeforces - 133B - Unary (水题)

原题链接:http://codeforces.com/problemset/problem/133/B

B. Unary
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output

Unary is a minimalistic Brainfuck dialect in which programs are written using only one token.

Brainfuck programs use 8 commands: “+”, “-“, “[“, “]”, “<”, “>”, “.” and “,” (their meaning is not important for the purposes of this problem). Unary programs are created from Brainfuck programs using the following algorithm. First, replace each command with a corresponding binary code, using the following conversion table:

“>”  →  1000,
“<”  →  1001,
“+”  →  1010,
“-”  →  1011,
“.”  →  1100,
“,”  →  1101,
“[”  →  1110,
“]”  →  1111.
Next, concatenate the resulting binary codes into one binary number in the same order as in the program. Finally, write this number using unary numeral system — this is the Unary program equivalent to the original Brainfuck one.

You are given a Brainfuck program. Your task is to calculate the size of the equivalent Unary program, and print it modulo 1000003 (106 + 3).

Input
The input will consist of a single line p which gives a Brainfuck program. String p will contain between 1 and 100 characters, inclusive. Each character of p will be “+”, “-“, “[“, “]”, “<”, “>”, “.” or “,”.

Output
Output the size of the equivalent Unary program modulo 1000003 (106 + 3).

Examples
input
,.
output
220
input
++++[>,.<-]
output
61425
Note
To write a number n in unary numeral system, one simply has to write 1 n times. For example, 5 written in unary system will be 11111.

In the first example replacing Brainfuck commands with binary code will give us 1101 1100. After we concatenate the codes, we’ll get 11011100 in binary system, or 220 in decimal. That’s exactly the number of tokens in the equivalent Unary program.

题目大意:
给出规则,以上 8 个字符分别用二进制数表示 . 要求对带以上 8 字符的字符串所组成的二进制数求其十进制数。

分析:
不难发现,这 8 个字符对应的十进制数分别是 8 9 10 11 12 13 14 15.

AC代码思路:
根据位运算,将字符串顺序读取,计算 .

AC代码实现:

#include <iostream>
#include <cstring>
using namespace std;
#define mod 1000003;
char s[105];
char b[]={"><+-.,[]"};//将这8个字符按照顺序存入数组

int main()
{
    cin>>s;
    int len=strlen(s);
    int sum=0;
    for (int i=0;i<len;i++)
    {
        for (int j=0;j<8;j++)
        {
            if (s[i]==b[j])
            {
                sum<<=4;//将二进制数进4位,即为下边一个字符所代表的二进制数腾出位置,同时进4位也代表 sum*=16
                sum+=8+j;//加入下一位字符所表示的十进制数
                sum%=mod;
            }
        }
    }

    cout<<sum<<endl;
}
//这是一种很聪明的写法,利用二进制的进位机制,避开了繁琐的进制转换。

未AC代码实现:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
char s[120];
int b[120];


long long quick_pow(int x,int y)
{
    if (y==0) return 1;
    return x*quick_pow(x,y-1)%1000003;
}

/*long long quick_pow(int x,int y)
{
    if (y==0) return 1;
    if (y%2==0) return quick_pow(x,y/2)*quick_pow(x,y/2);
    return  quick_pow(x,y/2) * quick_pow(x,y/2)*x;
}*/

int main()
{
    scanf ("%s",s+1);
    int len=strlen(s+1);
    int x=4*len;

    for (int i=len;i>=1;i--)//将字符转换成二进制数,存入数组 b[] 
    {
        if (s[i]=='>')
        {
            b[--x]=0;b[--x]=0;b[--x]=0;b[--x]=1;
        }
        if (s[i]=='<')
        {
            b[--x]=1;b[--x]=0;b[--x]=0;b[--x]=1;
        }
        if (s[i]=='+')
        {
            b[--x]=0;b[--x]=1;b[--x]=0;b[--x]=1;
        }
        if (s[i]=='-')
        {
            b[--x]=1;b[--x]=1;b[--x]=0;b[--x]=1;
        }
        if (s[i]=='.')
        {
            b[--x]=0;b[--x]=0;b[--x]=1;b[--x]=1;
        }
        if (s[i]==',')
        {
            b[--x]=1;b[--x]=0;b[--x]=1;b[--x]=1;
        }
        if (s[i]=='[')
        {
            b[--x]=0;b[--x]=1;b[--x]=1;b[--x]=1;
        }
        if (s[i]==']')
        {
            b[--x]=1;b[--x]=1;b[--x]=1;b[--x]=1;
        }
    }
    long long sum=0;
    for (int i=0;i<4*len;i++)
    {
        if (b[i]==1)
        {
            sum+=quick_pow(2,(4*len)-i-1);//根据二进制转换十进制的规则,其值与 1 的出现位置有关,则只要求出每个 1 所代表的十进制数值,再求和,即可得到 sum
            sum%=1000003;
        }
    }
    cout<<sum<<endl;
}
//这个方法很暴力,粗暴,也是我读完题目第一想法,但是理论上确实是可行的。至于为什么不能 AC 我也是很郁闷,因为得到的答案是正确的,但是在 run 的时候会出现程序错误而强行终止。小弟不是很懂,若哪位大神看出端倪希望可以留言指正。跪拜!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值