[C++]UVaLive7324 ASCII Addtion

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个字符,那么宽度就是5n;n个字符间有n-1个'.',所以行的总长度就是5n+n-1 = 6*n-1 = len,推出n=(len+1)/6

Code

#include <cstdio>
#include <cstring>
#include <cmath>
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\n",ccout[i]);
        memset(ccin,0,sizeof(ccin)); memset(ccout,0,sizeof(ccout));
    }
    return 0;
}

转载于:https://www.cnblogs.com/1Kasshole/p/9732707.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值