CSU - 1850 Grade School Multiplication 模拟乘法竖式

题目:

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1850

题意:

模拟乘法竖式,不过有以下几点不同:
- 竖式运算中间过程中某一行为全部0时,此行不输出,而在下一行输出后补0,若下一行也是0,那么就在下下行补两个0,以此类推
- 按照上述规则,若中间的运算步骤只有一行且就是最后乘积,那么省略中间过程

思路

很恶心的一个模拟题,主要是格式比较麻烦。首先算出乘积,决定输出的列数。对于某一行全为0的情况,开一个计数变量,遇到不为0的某一行时,把0补在后面,并把计数清空。如果某一行的值等于乘积(实际此时就只有一行),直接break,防止多输出中间过程,其余的看代码和注释

#include 

using namespace std;

typedef long long ll;
const int N = 1010;
int cas = 0;
void print_char(int n, char ch)
{
    for(int i = 0; i < n; i++) printf("%c", ch);
}
int main()
{
    ll a, b;
    while(scanf("%lld%lld", &a, &b), a || b)
    {
        ll res = a*b;
        int len = log10(1.0*res) + 1, len_a = log10(1.0*a) + 1, len_b = log10(1.0*b) + 1;
        printf("Problem %d\n", ++cas);
        print_char(len-len_a, ' '); printf("%lld\n", a);
        print_char(len-len_b, ' '); printf("%lld\n", b);
        print_char(len, '-'); printf("\n");
        int num = 0;
        bool flag = true;
        for(int i = 0; b; i++, b /= 10)
        {
            int t = b % 10;
            if(t == 0)//乘数为0,当前行数字必为0,计数变量加1
            {
                num++; continue;
            }
            ll c = t * a;
            int t_num = num;
            ll t_c = c;
            while(t_num--) t_c *= 10;
            if(t_c == res)//判断有没有某一行数字等于乘积,若等于就跳出
            {
                flag = false; break;
            }
            int len_c = log10(1.0*c) + 1;
            print_char(len-len_c-i, ' ');//前面所打印的空格应该是总列数-当前行数字长度-当前行数字后面的空格
            printf("%lld", c);
            print_char(num, '0');//补0
            print_char(i-num, ' ');//减去补0的数目,才是真正要打印的空格数目
            num = 0;
            printf("\n");
        }
        if(flag)
        {
            print_char(len, '-'); printf("\n");
        }
        printf("%lld\n", res);
    }
    return 0;
}

你可能感兴趣的:(各种水)