问题:
输入一个数集。找出所有形如abc*de(三位数乘以两位数)的算式。使得在完整的竖式中,所有数字都属于一个特定的数字集合(全由数集中的数字组成)
输出数字集合(相邻数字之间无空格)。
本文提供2种方法。请读者选择自己喜欢的方法。
第一种是作者自己编写的。比较繁琐。
第二种是在书籍上摘抄的。这种方法比较简单,容易理解,可读性强
第一种:
//竖式问题
//作者是将大多数计算数据以字符数组保存,进行运算
#include<stdio.h>
#include<string.h>
int main122()
{
char num1[6] = { 0 }, num2[6] = {0}; //num1 表示第一乘数(上面一个) num2则是第二个(下面一个)
char res1[10] = { 0 }, res2[10] = { 0 }, res[10] = { 0 };
int i, j, k,m, n,a,b,c,d,e; //进行循环的变量
int add1, add2, good1, good2, good3, end = 1;
int A, B, C, D, E;
char sum[10] = {0};
scanf_s(“%s”, sum, 10); //获取数集
for (i = 0; i < strlen(sum); i++)
sum[i] -= ‘0’; //将数集的元素的ASCII值 = 0;
sum[strlen(sum)] = 0; //目的是将’\0’赋值成 0(这个语句是多余的,没有意义).因为’\0′ == 0 ;
for (a = 0; a < strlen(sum); a++)
{
num1[3] = sum[a]; //第一个数,百位
for (b = 0; b < strlen(sum); b++)
{
num1[4] = sum[b]; //第二个数,十位
for (c = 0; c < strlen(sum); c++)
{
num1[5] = sum[c]; //第三个数字,个位
for (d = 0; d < strlen(sum); d++)
{
num2[4] = sum[d]; //另一个乘数,十位
for (e = 0; e < strlen(sum); e++)
{
num2[5] = sum[e]; //另一个,个位
//重置数值以便下一次的循环计算
for (i = 0; i <= 5; i++)
{
res1[i] = 0;
res2[i] = 0;
res[i] = 0;
}
/*______________开始运算_______________*/
for (i = 0; i < 3; i++) //计算与另一个乘数个位的相乘
{
A = (num1[5 – i] ) * (num2[5] ); //计算一个数各个位数与另一个个位相乘的积
res1[5-i] += A % 10; //得到积的个位数
if (res1[5 – i] >= 10) //相加满10情况
{
res1[4 – i] ++; //前一位 +1
res1[5 – i] -= 10; //该位 -10
}
res1[4 – i] += A / 10; //前一位得到进位的数字 因为最大 9×9 = 81,8 +1 <10恒成立,所以无需再考虑进位问题
}
for (i = 0; i < 3; i++) //计算与另一个乘数十位的相乘
{
A = (num1[5 – i] ) * (num2[4] ); //计算一个数各个位数与另一个个位相乘的积
res2[4 – i] += A % 10;
if (res2[4 – i] >= 10) //相加满10情况
{
res2[3 – i] ++;
res2[4 – i] -= 10;
}
res2[3 – i] += A / 10;
}
//2个积相加
for (i = 5; i >= 0; i–)
{
/*
if语句是根据一开始的数组的值为‘0’~‘9’(已经全部修改),所以 -‘0’后的条件为0~9;
后来全部数组的值都修改成了0~9,所以-‘0’的语句全部去掉了
但是if语句已经全部写完,去掉很麻烦,而且去掉后不知道会不会出现问题。
就算存在if语句也不影响程序操作,所以保留
*/
if ((res1[i] >= 0) && (res[i] <= 9))
add1 = res1[i];
else
add1 = 0; //原先res1,res2的值存在未赋值的值,所以当不执行if语句,就赋值0
if ((res2[i] >= 0) && (res2[i] <= 9))
add2 = res2[i];
else
add2 = 0;
res[i] += add1 + add2;
if (res[i] >= 10) //进位
{
res[i – 1]++;
res[i] -= 10;
}
}
//打印
good1 = -1, good2 = -1, good3 = -1;
//判断是否需要打印(符合条件的打印出来)
//以下的代码,其实一个内置函数就能解决
//只是当时不知道这个函数,后来看了书才知道
//string.h里的strchr函数,具体用法在另一个算法里有介绍
for (i = 0; i <= 5; i++)
{
for (j = 0; j <= strlen(sum); j++)
{
if (sum[j] != res1[i])
{
good1++;
}
else
{
good1 = -1;
break;
}
}
for (j = 0; j <= strlen(sum); j++)
{
if (sum[j] != res2[i])
{
good2++;
}
else
{
good2 = -1;
break;
}
}
for (j = 0; j <= strlen(sum); j++)
{
if (sum[j] != res[i])
{
good3++;
}
else
{
good3 = -1;
break;
}
}
if ((good1 != -1) || (good2 != -1) || (good3 != -1))
break;
}
//注意:打空格补齐最为简便的方法是 %6d (不足6位前面补空格)
//作者空格补齐的方法瑕疵比较大,仅供参考
//如果是使用 %6d 补齐空格,打印这一步其实可以使用一个printf就可以结束,这样可以大大减少代码量
if ((good1 == -1) && (good2 == -1) && (good3 == -1))
{
printf(“\n第%d个:\n”,end);
end++;
printf(” “);
for (i = 3; i <= 5; i++)
{
printf(“%d”, num1[i]);
}
printf(“\n”);
printf(“X “);
for (i = 4; i <= 5; i++)
{
printf(“%d”, num2[i]);
}
printf(“\n——\n”);
for (i = 0; i <= 5; i++)
{
if ((res1[i] == 0)&&(i<=2))
{
printf(” “);
}
else
printf(“%d”, res1[i]);
}
printf(“\n”);
for (i = 0; i <= 5; i++)
{
if ((res2[i] == 0) && ((i < 2)||(i==5)))
{
printf(” “);
}
else
printf(“%d”, res2[i]);
}
printf(“\n——\n”);
for (i = 0; i <= 5; i++)
{
if ((res[i] == 0) && (i < 2))
{
printf(” “);
}
else
printf(“%d”, res[i]);
}
}
}
}
}
}
}
return 0;
}
————————————————————————————————————————————————————————————————
——————————————————————————本程序在VS2017上运行成功——————————————————————————
————————————————————————————————————————————————————————————————
第二种:
本中方法犹豫不同编译器问题,作者没有运行,请读者自行运行
若是发现代码有问题,麻烦告诉我(检查过一遍没有错误,VC也编译过,不过有个警告无法解决,所以未运行)
#include<stdio.h>
#include<string.h>
int main()
{
int count = 0;
char s[20], buf[99];
scanf(“%s”, s);
for(int abc = 111; abc <= 999;abc++)
for (int de = 11; de <= 99; de++)
{
int x = abc * (de % 10), y = abc * (de / 10), z = abc * de;
sprintf(buf, “%d%d%d%d%d”, abc, de, x, y, z);
int ok = 1;
for (int i = 0; i < strlen(buf); i++)
{
if (strchar(s, buf[i]) == NULL) ok = 0;
}
if (ok)
{
printf(“<%d>\n”, ++count);
printf(“%5d\nX%4d\n—–\n%5d\n%4d\n—–\n%5d\n\n”, abc, de, x, y, z);
}
}
printf(“The number of solutions = %d\n”, count);
return 0;
}
//sprintf 与 strchr。
strchr 作用是在一个字符串中查找单个字符
sprintf 与 printf , fprintf是“兄弟”。
printf输出到屏幕
fprintf输出到文件
sprintf输出到字符串。
具体请读者百度查询。