竖式问题(两种方法)

题目描述

找出所有形如 abcde (三位数乘以两位数)的算式,使得在完整的竖式中,所有数字都属于一个特定的数字集合。输入数字集合(相邻数字之间没有空格),输出所有竖式。每个竖式前应有编号,之后应有一个空行。最后输出解的总数。具体格式见样例输出。

输入

输入包含多组测试用例。

对于每组测试用例,输入一个字符串s,代表数字集合。

输出

输出所有竖式。每个竖式前应有编号,之后应有一个空行。最后输出解的总数。(竖式按照3位数的大小从小到大输出~)

样例输入

2357

样例输出

<1>

775

X 33

-----

2325

2325

-----

25575

The number of solutions: 1

这道题分类:“简单”、”语言入门“

虽然但是,它好像真的不简单。(感觉是我太菜了)

先上最终的代码:

#include <stdio.h>
#include <string.h>
int cmp(const void* a, const void* b)
{
    return *(char*)a - *(char*)b;
}
void del_1(char* p) {
    int len = strlen(p);
    for (int i = 0;i < len;i++) {
        int k = i + 1;
        for (int j = i + 1;j < len;j++) {
            if (p[j] != p[i])
                p[k++] = p[j];
        }
        p[k] = '\0';
    }
}
int main()
{
    char a[1000];
    while ((scanf("%s", a)) != EOF)
    {
        del_1(a);
        int n = strlen(a);
        int th, tw;
        int flag1 = 1;
        qsort(a, n, sizeof(a[0]), cmp);
        int A, B, C, D, E;
        int sum = 0;
        for (A = 0;A < n;A++)
        {
            for (B = 0;B < n;B++)
            {
                for (C = 0;C < n;C++)
                {
                    for (D = 0;D < n;D++)
                    {
                        for (E = 0;E < n;E++)
                        {
                            if (a[A] == '0')
                                goto outa;
                            if (a[D] == '0')
                                goto outd;
                            th = (a[A] - 48) * 100 + (a[B] - 48) * 10 + (a[C]-48);
                            tw = (a[D] - 48) * 10 + (a[E]-48);
                            int mid1 = th * (tw % 10);
                            int mid2 = th * (tw / 10);
                            int res = th * tw;
                            char b[100];
                            int lenb, i;
                            sprintf(b, "%d%d%d", mid1, mid2, res);
                            lenb = strlen(b);
                            for (i = 0;i < lenb; i++)
                            {
                                if (strchr(a, b[i]) == NULL)
                                    flag1 = 0;
                            }
                            if (flag1 == 1)
                            {
                                printf("<%d>\n%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n\n", sum + 1, th, tw, mid1, mid2, res);
                                sum++;
                            }
                            flag1 = 1;
                        }
                    outd:;
                    }
                }
            }
        outa:;
        }
            printf("The number of solutions: %d\n", sum);
    }
}

思路大致是,先把所给字符串中的重复字符删去,然后对其中的字符进行由小到大排序,然后进行五个for循环嵌套,采取历遍的方式。

其中运用到两个函数:sprintf()和strchr()函数,下面介绍一下:

  1. sprintf函数:

这个在当初学习零件库的时候有学到过。这个函数是可以把数字转化为字符串。头文件为<stdio.h>。

其最基础的用法是:

sprintf(s, "%d", 123);//可使s变为含有'123'的字符串。

其次有:

sprintf(s, "%8d%8d", 123, 4567); // 可使s变为含有'*****123****4567'的字符串,‘8’用来确定位数,不足的会在数字左边补空白。(其中*代表空格)

当然加上‘-’可以实现左对齐:

sprintf(s, "%-8d%-8d", 123, 4567); // 可使s变为含有'123*****4567****'的字符串。

还有:

sprintf(s, "%08d", 123); // 产生:"00000123"的字符串

对于小数:

sprintf(s, "%f", 1.23456789); // 产生 "1.234567",默认保留后六位小数。

相同的:%m.nf”格式,其中m表示打印的宽度,n表示小数点后的位数。类似于%d,就不举例了。

  1. strchr函数

strchr 函数原型的一般格式如下:

char *strchr(const char *s, int c);

它表示在字符串 s 中查找字符 c,返回字符 c 第一次在字符串 s 中出现的位置,如果未找到字符 c,则返回 NULL。

上面这个代码是oj通过的代码,下面这个是你去查竖式问题,统一会给的代码,类似于如下的答案:

#include <stdio.h>
#include <string.h>
int main()
{
    char a[11];
    int i, j;
    while ((scanf("%s", a)) != EOF)
    {
        char th[100];
        int lenth;
        int flag1 = 1;
        int abc, de;
        int sum = 0;
        for (abc = 111;abc < 1000;abc++)
        {
            for (de = 11;de < 100;de++)
            {
                int mid1, mid2, res;
                mid1 = abc * (de % 10);
                mid2 = abc * (de / 10);
                res = abc * de;
                sprintf(th, "%d%d%d%d%d", abc,de,mid1,mid2,res);
                lenth = strlen(th);
                for (i = 0;i < lenth; i++)
                {
                    if (strchr(a, th[i]) == NULL)
                        flag1 = 0;
                }
                if (flag1 == 1)
                {
                    printf("<%d>\n%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n",sum+1, abc, de, mid1, mid2, res);
                    sum++;
                }
                flag1 =  1;
            }
        }
        printf("\nThe number of solutions: %d\n", sum);
    }
}

这个是采取历遍的方式,其实我感觉这种方法更加清晰,但是放到oj上是时间超限的。

仅供参考吧,也算是两种解题思路了。

### 计算方法详解 计算是一种基础的手动算术运算方,在编程中模拟这种算法可以加深对基本数学操作的理解。对于大数相乘或者特定场景下的数值处理非常有用。 #### 模拟乘法的核心概念 在不将字符串转换成整型的情况下实现两数相乘,关键是模仿手工完成多位数乘法的过程: - 将每一位上的数字单独取出并与另一个完整的被乘数逐位相乘; - 记录每次部分积的结果并考虑位置偏移(即错开相应的位置),最终累加以获得总和作为最终结果[^1]。 #### Python代码实例展示如何模拟乘法 下面是一个具体的例子来说明怎样通过Python程序实现上述逻辑: ```python def multiply_strings(num1, num2): if num1 == "0" or num2 == "0": return "0" result = [0] * (len(num1) + len(num2)) for i in range(len(num1)-1, -1, -1): carry = 0 for j in range(len(num2)-1, -1, -1): temp_sum = int(num1[i]) * int(num2[j]) + result[i+j+1] + carry result[i+j+1] = temp_sum % 10 carry = temp_sum // 10 result[i] += carry # Convert list to string and remove leading zeros. result_str = ''.join(map(str, result)).lstrip("0") return result_str if result_str != "" else "0" print(multiply_strings("123", "456")) # 输出:"56088" ``` 此函数接收两个由字符组成的非负整数串`num1`和`num2`,返回它们的乘积累计值同样是以字符串的形给出。这里采用逆序遍历的方来进行每位之间的相乘,并妥善管理进位情况以确保准确性[^3]。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值