题目来自于刘汝佳编著的《算法竞赛入门经典(第二版)》
问题描述:
找出形如 abc*de (三位数乘以两位数) 的算式,使得在完整的竖式中,所有数字属于一个特定的数字集合。输入数字集合 (相邻数字之间没有空格),输出所有竖式。每个竖式前应有编号,之后应有一个空行。最后输出解的总数。样例输入:
2357
样例输出:
分析:1、如果从字符集入手,通过组合的方法,选取abc和de。无法保证竖式中的元素全部在字符集中。还是要进行判断。
且循环 层次较多 。
2、从要求的格式出发建立两层循环就好多了。
3、书上的代码,是将竖式中的所有元素通过sprintf函数放入buff中。
书上的源程序没有问题,但是我在尝试输出buff(缓冲区)中的内容时出现了一些问题。
4、后来干脆舍弃了sprintf这种方式。但是我如果想将int形的数据作为char,通过strcat连接函数,连接在一起,有点麻烦。
5、在网上看到另一种接法,直接判断数字是否在字符集中。用多次判断的方法取代连接字符串,挺好。
6、用字符串数组处理也挺好的,用不上string类。
书上的代码:
#include<stdio.h>
#include<string.h>
int main() {
char s[20], buf[99];
int count = 0;
scanf("%s", s);
for (int abc = 100; abc <= 999; abc++)
{
for (int de = 10; de <= 99; de++)
{
int x = abc*(de % 10);
int y = abc*(de / 10);
int 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 (strchr(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 numbver of solutions = %d\n", count);
return 0;
}
用函数写的代码:
#include<iostream>
#include<string.h>
using namespace std;
int inset(char *s,int num)//判断数字是否在数字集中
{
int len=strlen(s),i,tmp;
while(num)
{
tmp=num%10;
for(i=0;i<len;i++)
{
if(s[i]-'0'==tmp)
break;
}
if(i==len)//不在里面,因为循环结束跳出的循环
return 0;
num=num/10;
}
return 1;
}
int main()
{
int i,count=0;
char s[10];
scanf("%s",s);
//printf("%s\n",s);
int abc,de,x,y,z;
for(abc=111;abc<=999;abc++)
{
for(de=11;de<=99;de++)
{
x=abc*(de%10);
y=abc*(de/10);
z=abc*de;
if(inset(s,abc)&&inset(s,de)&&inset(s,x)&&inset(s,y)&&inset(s,z))
{
count++;
printf("<%d>\n", count);
printf("%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n\n", abc, de, x, y, z);
}
}
}
return 0;
}
结果:
两段代码共同的一点:对竖式中重复出现的字符,进行了重复的判断,判断其是否在字符集中。
参考文章:
https://www.cnblogs.com/Breathmint/p/7217046.html