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

[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

Input Output Notes
3
Number of operations; no output for this line
3 + 5 Invalid Neither number is valid
9987654321 + 1 A000000000
-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 ;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章