[C++]UVaLive7324 ASCII Addtion

8164 ワード

Description
Nowadays, there are smartphone applications that instantly translate text and even solve math problems if you just point your phone’s camera at them. Your job is to implement a much simpler functionality reminiscent of the past — add two integers written down as ASCII art. An ASCII art is a matrix of characters, exactly 7 rows high, with each individual character either a dot (.) or the lowercase letter ‘x’. An expression of the form a + b is given, where both a and b are positive integers. The expression is converted into ASCII art by writing all the expression characters (the digits of a and b as well as the ‘+’ sign) as 7 × 5 matrices, and concatenating the matrices together with a single column of dot characters between consecutive individual matrices. The exact matrices corresponding to the digits and the ‘+’ sign are as folows:
xxxxx   ....x   xxxxx   xxxxx   x...x   xxxxx   xxxxx   xxxxx   xxxxx   xxxxx   .....
x...x   ....x   ....x   ....x   x...x   x....   x....   ....x   x...x   x...x   ..x..
x...x   ....x   ....x   ....x   x...x   x....   x....   ....x   x...x   x...x   ..x..
x...x   ....x   xxxxx   xxxxx   xxxxx   xxxxx   xxxxx   ....x   xxxxx   xxxxx   xxxxx
x...x   ....x   x....   ....x   ....x   ....x   x...x   ....x   x...x   ....x   ..x..
x...x   ....x   x....   ....x   ....x   ....x   x...x   ....x   x...x   ....x   ..x..
xxxxx   ....x   xxxxx   xxxxx   ....x   xxxxx   xxxxx   ....x   xxxxx   xxxxx   .....

Given an ASCII art for an expression of the form a + b, find the result of the addition and write it out in the ASCII art form.
Input
The input file contains several test cases, each of them as described below. Input consists of exactly 7 lines and contains the ASCII art for an expression of the form a + b, where both a and b are positive integers consisting of at most 9 decimal digits and written without leading zeros.
Output
For each test case, output 7 lines containing ASCII art corresponding to the result of the addition, without leading zeros.
Sample Input
....x.xxxxx.xxxxx.x...x.xxxxx.xxxxx.xxxxx.......xxxxx.xxxxx.xxxxx
....x.....x.....x.x...x.x.....x.........x...x...x...x.x...x.x...x
....x.....x.....x.x...x.x.....x.........x...x...x...x.x...x.x...x
....x.xxxxx.xxxxx.xxxxx.xxxxx.xxxxx.....x.xxxxx.xxxxx.xxxxx.x...x
....x.x.........x.....x.....x.x...x.....x...x...x...x.....x.x...x
....x.x.........x.....x.....x.x...x.....x...x...x...x.....x.x...x
....x.xxxxx.xxxxx.....x.xxxxx.xxxxx.....x.......xxxxx.xxxxx.xxxxx

Sample Output
....x.xxxxx.xxxxx.xxxxx.x...x.xxxxx.xxxxx
....x.....x.....x.x.....x...x.x.........x
....x.....x.....x.x.....x...x.x.........x
....x.xxxxx.xxxxx.xxxxx.xxxxx.xxxxx.....x
....x.x.........x.....x.....x.....x.....x
....x.x.........x.....x.....x.....x.....x
....x.xxxxx.xxxxx.xxxxx.....x.xxxxx.....x

Analyze:
現在、最も気持ち悪いシミュレーション問題の一つに遭遇したことがある.練習試合でchar肝を使っている私だけが一瞬冷や汗をかいたと聞いた.それぞれの境界計算で頭が大きくなった.一つの気持ち悪い点はこの問題が与えたサンプルが一つしかないが、特に自分でサンプルを書くのは面倒なロットだ.ここでは、自分で書いたサンプルを提供します.
....x.xxxxx.......xxxxx
....x.....x...x...x...x
....x.....x...x...x...x
....x.xxxxx.xxxxx.xxxxx
....x.x.......x...x...x
....x.x.......x...x...x
....x.xxxxx.......xxxxx

問題の例も加えればほとんど問題ありません.
中のdigitsのアルゴリズムは方程式によって得られた.文字(数字またはプラス記号)の幅は5で、n文字があると仮定すると、幅は5 nである;n文字の間にn-1'.'があるので、行の総長さは5 n+n-1=6*n-1=lenであり、n=(len+1)/6を押し出す
Code
#include 
#include 
#include 
struct Num{
    const char* n[7];   //            7         
}nums[11]={
        {
                "xxxxx",
                "x...x",
                "x...x",
                "x...x",
                "x...x",
                "x...x",
                "xxxxx"
        },
        {
                "....x",
                "....x",
                "....x",
                "....x",
                "....x",
                "....x",
                "....x"
        },
        {
                "xxxxx",
                "....x",
                "....x",
                "xxxxx",
                "x....",
                "x....",
                "xxxxx"
        },
        {
                "xxxxx",
                "....x",
                "....x",
                "xxxxx",
                "....x",
                "....x",
                "xxxxx"
        },
        {
                "x...x",
                "x...x",
                "x...x",
                "xxxxx",
                "....x",
                "....x",
                "....x"
        },
        {
                "xxxxx",
                "x....",
                "x....",
                "xxxxx",
                "....x",
                "....x",
                "xxxxx"
        },
        {
                "xxxxx",
                "x....",
                "x....",
                "xxxxx",
                "x...x",
                "x...x",
                "xxxxx"
        },
        {
                "xxxxx",
                "....x",
                "....x",
                "....x",
                "....x",
                "....x",
                "....x"
        },
        {
                "xxxxx",
                "x...x",
                "x...x",
                "xxxxx",
                "x...x",
                "x...x",
                "xxxxx"
        },
        {
                "xxxxx",
                "x...x",
                "x...x",
                "xxxxx",
                "....x",
                "....x",
                "xxxxx"
        },
        {
                ".....",
                "..x..",
                "..x..",
                "xxxxx",
                "..x..",
                "..x..",
                "....."
        }
};
char ccin[7][120];      //        
char ccout[7][120];     //          
int cmp(int index){     //                  
    for(int m = 0;m < 10;m ++){
        bool ok = true;
        for(int i = 0;i < 7;i ++)
            for(int j = 0;j < 5;j ++)
                if(nums[m].n[i][j]!=ccin[i][j+index]){ ok=false; break;}
        if(ok) return m;
    }
    return -1;  //               ,  -1
}
int ccount(int sum){        //      
    int c = 0;
    while(sum){
        sum /= 10; ++c;
    }
    return c;
}
int main()
{
    while(~scanf("%s",ccin[0])){
        for(int i = 1;i < 7;i ++) scanf("%s",ccin[i]);
        int len = strlen(ccin[0]);
        int digits = (len+1)/6;     //        
        int sum = 0,mul = 1,i;
        for(i = 0;i < digits;i ++){
            int bit = cmp(len-1-(4+i*6));
            if(bit<0){ len = len-1-(4+i*6)-1; break; }
            sum += bit*mul; //   
            mul *= 10;
        }
        digits -= i + 1; mul = 1;
        for(i = 0;i < digits;i ++){
            int bit = cmp(len-1-(4+i*6));
            sum += bit*mul;
            mul *= 10;
        }
        int final = ccount(sum);
        for(i = 0;i < final;i ++){
            int e = 1;
            for(int l = 0;l < final - 1 - i;l ++)
                e*=10;
            int bit = sum / e;
            sum-=e*bit;
            for(int j = 0;j < 7;j ++){
                for(int k = 0;k < 5;k ++)
                    ccout[j][k+i*6] = nums[bit].n[j][k];
                if(i!=final-1) ccout[j][(i+1)*6-1]='.';
            }
        }
        for(i = 0;i < 7;i ++)
            printf("%s
",ccout[i]); memset(ccin,0,sizeof(ccin)); memset(ccout,0,sizeof(ccout)); } return 0; }