找出所有形如abc*de(三位数乘以两位数)的算式,使得在完整的竖式中,所有数字都属于一个特定的数字集合。输入数字集合(相邻数字之间没有空格),输出所有竖式。每个竖式前应有编号,之后应有一个空行。最后输出解的总数。具体格式见样例输出(为了便于观察,竖式中的空格改用小数点显示,但所写程序中应该输出空格,而非小数点)。
样例输入:
2357
样例输出:
<1>
. . 7 7 5
X . . 3 3
_ _ _ _ _
. 2 3 2 5
2 3 2 5 .
_ _ _ _ _
2 5 5 7 5
The number of solutions = 1
分析:
1.首先我们先理解题意,如果连题目都理解不了的话,这道题当然 做不出来了。这道题就是说将所用的3位数乘以2位数,并用竖式展示出来。但是要由我们输入的数,组成这两个数,而且在竖式计算中,我们输入的数必须都出现在竖式之中。而且每个竖式都有编号,升序,最后还要输出一共有多少个竖式。
2.现在我们开始代码设计,看到"相邻数字之间没有空格"所以肯定是要用字符来输入,用字符组来储存。记总数,和升序编号我们可以用一个变量做for循环++当编号,最后再输出的变量就是总数。还得判定abc*de是否为一个合法的竖式,就要if语句用strchr来查询字符组中的字符是否在竖式中存在。
分析结束上代码,我会对代码中的一些细节再做讲解
#include<stdio.h>
#include<string.h>
int main(){
int count = 0;
char s[20],buf[99]; // 这里将字符组尽量设大一点
scanf("%s", s); // 注意scanf输入字符","后是不需要&的直接s就行
// 下面两个for循环拿到所有的两位数三位数
for(int abc = 100; abc <= 999; abc++){
for(int de = 10; de <= 99; de++){
// 分别拿到个位乘abc,十位乘abc,以及计算结果
int x = abc * (de%10), y = abc * (de/10), z = abc * de;
// 用sprintf把整型类型转字符串,并输出到buf中
sprintf(buf, "%d%d%d%d%d", abc, de, x, y, z);
// 设置ok变量方便判断是否将竖式打印
int ok = 1;
// strlen()用来计算字符串的长度,且不包括结束字符"\0"。
for(int i = 0; i < strlen(buf); i++){
// 判断buf中是否有s中的字符,没有就将变量ok = 0
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 number of solutions = %d\n", count);
return 0;
}
这道题是在《算法竞赛入门》里的一题,作者是在代码中将abc = 111,de = 11,我查了很关于为什么这里的111不能是100,但是也没有找到原因,所以就把代码写成abc = 100,de = 10,有人说作者在这里可能有弦外之音,我也不咋懂,如果有明白为什么不能为100的人麻烦评论告诉一下。
简单说一下strchr()是查询字符组中是否有某个字符的,如果没有则返回NULL。
sprintf()是输出到字符串中,而且可以将各种基础类型转字符串,printf是输出到屏幕,fprintf是输出到文件。