BNU All Your Base (Regionals 2011, North America - South Central USA) - from lanshui_Yang

来源:互联网 发布:gradle 设置java版本 编辑:程序博客网 时间:2024/04/29 12:45

[PDF Link]

Premise: Given a specification for a “base” (well, actually a mixed radix number system), take in pairs of numbers written in our “base”, perform a specified operation on them and output the result in our base.

The Base: A number system where the right-most digit (digit 1) can be a counting number between 0 and 1, the second right-most digit (digit 2) can be a counting number between 0 and 2 and, more generally, each digit n (as labeled from the right) can have values between 0 and n. After 9, upper case letters are used, starting with A and going through Z. After the highest digit (which can be 0-Z), no further digits are possible; any numbers which go past that digit are invalid. Negative numbers are prefixed with a single “-” sign. Numbers never have leading zeros, with the exception of zero itself, which is represented by a single “0” character.

Operations: Addition (+) and subtraction (-): The numbers are added or subtracted as normal (including carrying, borrowing, etc).

Input

  • The first line of input is the number (base 10) of operations that need to be performed.
  • Each following line will be at most 1000 bytes and will consist of a variable-radix number, a space, a single character indicating the operation (+, or -), a space, another variable-radix number, and a newline (LF).
  • Either number for any operation (and also the result) may be negative.

Output

  • For each operation in the input, a single line of output should be produced containing either the result (a variable-radix number) or the string “Invalid”) (without quotes) followed by a newline (LF).
  • If either of the input numbers or the resulting number is not valid in the number system, or an error is encountered while performing the operation, the result is invalid.

Sample Input

InputOutputNotes3
Number of operations; no output for this line3 + 5InvalidNeither number is valid9987654321 + 1A000000000
-A000000000 - 1-A000000001

  题目大意:有一种数制(假设为数制base ),从右往左算起,第一位数字(即个位)的范围是0~1 ,第二位数字的范围是 0~2 ,第三位是0~3,……,第十位是 0~A , ……,一直到第35位的数字范围是0~Z。现在给你一个算式,形式是A + B 或 A - B,其中A、B均是数,并且可正可负。让你判断给出的算式中的两个数A 和 B是否是数制base 的数 ,如果有一个不是则输出Invalid ,如果A 、B合法,则计算出算式的结果,并判断结果是否是数制base的数,如果是,则输出结果,否则,输出Invalid。

        解题思路:这是一道数制方面的题,如果会java 的话,可以先把A、B转换成十进制下的数,相加或相减,算出结果后在转换回数制base下的数。我在这里用的是手动模拟数制加减,写了400多行,这是自我学编程以来写的最长的程序,纪念下,呵呵。

        请看代码:

#include<iostream>#include<cstring>#include<string>#include<cmath>#include<cstdio>#include<queue>#include<algorithm>#include<set>#include<vector>#define mem(a , b) memset(a , b , sizeof(a))using namespace std ;inline void RD(int &a){    a = 0 ;    char t ;    do    {        t = getchar();    }    while(t < '0' || t > '9') ;    a = t - '0';    while((t = getchar()) >= '0' && t <= '9')        a = a * 10 + ( t - '0' );}inline void OT(int a){    if(a >= 10)        OT(a / 10) ;    putchar(a % 10 + '0') ;}const int MAXN = 1111 ;const int MAXN2 = 40 ;int pan[MAXN2] ;char sx[MAXN] ;char sy[MAXN] ;char st[MAXN] ;char op ;int fx ;int fy ;int lenx , leny ;int fa ; // 记录结果符号void chu()  // 记录每一位数字的最大值{    int i ;    for(i = 0 ; i < MAXN2 ; i ++)    {        pan[i] = i + 1 ;    }}void init(){    mem(sx , 0) ;    mem(sy , 0) ;    mem(st , 0) ;    scanf("%s" , st) ;    lenx = strlen(st) ;    int i ;    for(i = 0 ; i < lenx ; i ++)    {        sx[i] = st[lenx - i - 1] ;    }    if(st[0] == '-')    {        fx = -1 ;        lenx -- ;        sx[lenx] = '\0' ;    }    else    {        fx = 1 ;    }    cin >> op ;    scanf("%s" , st) ;    leny = strlen(st) ;    for(i = 0 ; i < leny ; i ++)    {        sy[i] = st[leny - i - 1] ;    }    if(st[0] == '-')    {        fy = -1 ;        leny -- ;        sy[leny] = '\0' ;    }    else    {        fy = 1 ;    }}int shu(char s){    int t ;    if(s >= 'A' && s <= 'Z')    {        t = (s - 'A' + 10) ;    }    else        t = (s - '0') ;    return  t ;}int val(char *s , int len){    int i ;    for(i = 0 ; i < len ; i ++)    {        if(shu(s[i]) > pan[i])        {            return 0 ;        }    }    return 1 ;}int A[MAXN] ;int cnt = 0 ;char zf(int b){    if(b >= 0 && b <= 9)        return b + '0' ;    return b - 10 + 'A' ;}void print(){    if(A[35] != 0)        puts("Invalid") ;    else    {        if(fa == -1)            putchar('-') ;        int i ;        bool first = false ;        for(i = 34 ; i > 0 ; i --)        {            if(A[i] > 0 && !first)            {                first = true ;            }            if(first)            {                printf("%c" , zf(A[i])) ;            }        }        printf("%d\n" , A[0]) ;    }}int comp(char *s1 , int len1 , char *s2 , int len2){    if(len1 < len2)    {        return -1 ;    }    if(len1 > len2)    {        return 1 ;    }    else    {        int i ;        for(i = len1 - 1 ; i >= 0 ; i --)        {            if(shu(sx[i]) > shu(sy[i]))            {                return 1 ;            }            else if(shu(sx[i]) < shu(sy[i]))            {                return -1 ;            }        }        return 0 ;    }}void SUB(char *s1 , int len1 , char * s2 , int len2){    cnt = 0 ;    mem(A , 0) ;    int carry = 0 ;    int i ;    for(i = 0 ; i < len2 ; i ++)    {        int t1 = shu(s1[i]) + carry ;        int t2 = shu(s2[i]) ;        if(t1 >= t2)        {            A[cnt ++] = t1 - t2 ;            carry = 0 ;        }        else        {            t1 += (pan[i] + 1) ;            A[cnt ++] = t1 - t2 ;            carry = -1 ;        }    }    for(i = len2 ; i < len1 ; i ++)    {        int t1 = shu(s1[i]) + carry ;        int t2 = 0 ;        if(t1 >= t2)        {            A[cnt ++] = t1 - t2 ;            carry = 0 ;        }        else        {            t1 += (pan[i] + 1) ;            A[cnt ++] = t1 - t2 ;            carry = -1 ;        }    }}void solve1() // 正 + 正{    cnt = 0 ;    mem(A , 0) ;    int carry = 0 ;    if(lenx <= leny)    {        int i ;        for(i = 0 ; i < lenx ; i ++)        {            int tmp = shu(sx[i]) + shu(sy[i]) + carry ;            if(tmp > pan[i])            {                A[cnt ++] = tmp % (pan[i] + 1);                tmp /= (pan[i] + 1) ;                carry = tmp ;            }            else            {                A[cnt ++] = tmp ;                carry  = 0 ;            }        }        for(i = lenx ; i < leny ; i ++)        {            int tmp = shu(sy[i]) + carry ;            if(tmp > pan[i])            {                A[cnt ++] = tmp % (pan[i] + 1);                tmp /= (pan[i] + 1) ;                carry = tmp ;            }            else            {                A[cnt ++] = tmp ;                carry  = 0 ;            }        }        if(carry > 0)            A[cnt ++] = carry ;    }    else    {        int i ;        for(i = 0 ; i < leny ; i ++)        {            int tmp = shu(sx[i]) + shu(sy[i]) + carry ;            if(tmp > pan[i])            {              A[cnt ++] = tmp % (pan[i] + 1);                tmp /= (pan[i] + 1) ;                carry = tmp ;            }            else            {                A[cnt ++] = tmp ;                carry  = 0 ;            }        }        for(i = leny ; i < lenx ; i ++)        {            int tmp = shu(sx[i]) + carry ;            if(tmp > pan[i])            {               A[cnt ++] = tmp % (pan[i] + 1);                tmp /= (pan[i] + 1) ;                carry = tmp ;            }            else            {                A[cnt ++] = tmp ;                carry  = 0 ;            }        }        if(carry > 0)            A[cnt ++] = carry ;    }    print() ;}void solve2() // 正 - 正{    int cmp = comp(sx , lenx , sy , leny) ;    if(cmp == -1)  // sx < sy    {        SUB(sy , leny , sx , lenx) ;        fa = -1 ;        print() ;    }    else if(cmp == 0)    {        puts("0") ;        fa = 1 ;    }    else    {        SUB(sx , lenx , sy , leny) ;        fa = 1 ;        print() ;    }}void solve3() // 负 + 正{    int cmp = comp(sx , lenx , sy , leny) ;    if(cmp == -1)  // sx < sy    {        SUB(sy , leny , sx , lenx) ;        fa = 1 ;        print() ;    }    else if(cmp == 0)    {        puts("0") ;        fa = 1 ;    }    else    {        SUB(sx , lenx , sy , leny) ;        fa = -1 ;        print() ;    }}void solve(){    if(!val(sx , lenx) || !val(sx , leny))    {        puts("Invalid") ;    }    else    {        mem(A , 0) ;        int flag = 1 ;        if(fx == 1 && fy == 1)        {            if(op == '+')            {                fa = 1 ;                solve1() ;            }            else            {                solve2() ;            }        }        if(fx == 1 && fy == -1)        {            if(op == '+')            {                solve2() ;            }            else            {                fa = 1 ;                solve1() ;            }        }        if(fx == -1 && fy == 1)        {            if(op == '+')            {                solve3() ;            }            else            {                fa = -1 ;                solve1() ;            }        }        if(fx == -1 && fy == -1)        {            if(op == '+')            {                fa = -1 ;                solve1() ;            }            else            {                solve3() ;            }        }    }}int main(){    chu() ;    int T ;    scanf("%d" , &T) ;    while (T --)    {        init() ;        solve() ;    }    return 0 ;}