您的位置:首页 > 其它

初学acmer--读《算法竞赛入门经典》笔记(五)P41-45

2017-08-07 21:18 232 查看
题目:

竖式问题:找出所有形如abc*de(三位数乘以两位数)的算式,使得在完整的竖式中,所有数字都属于一个特定的数字集合(相邻数字之间没有空格),输出所有竖式。每个竖式前应该有编号,之后有一个空行。最后输出解的总数。具体格式见样例(样例中空格用小数点表示,但程序中应该输出空格,而非小数点)

样例输入;

2357

样例输出:

<1>

。。775

x 。。33

-----

。2325

2325。

-----

25575

The number of solution =1

分析:本题可以分解为两个部分:一是找出所有的解的组合,即abc和de所有可能的情况,二是检验找出解的情况正确与否

针对一,不难想到可以通过暴力枚举所有的三位数abc和两位数de。对于二,我们只要验证在竖式中出现的数字均属于集合即可,而这首先必须弄清是哪些数字出现了,又是如何出现的。对于竖式运算,我们再熟悉不过了,通过“模拟”运算过程,不难发现2325是775*3的结果,即abc*e,另一个是abc*d。那么最后的结果25575是如何来的呢,若是在真正的竖式计算中,那是由2325和2325错位相加得到的,可是“模拟”这个过程显然有些麻烦,那么有没有其他方法呢,这时就要“跳出”“模拟”的过程了,不要忘记计算机的计算属性,最后的结果对于计算机来说,可以轻易直接计算abc*de,何必需要模拟呢?

至此,整个算法已经显而易见了。下面贴上代码:

#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(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;
}


ps:①sprintf:格式化输出到字符数组中

         fprintf格式化输出到文件中

         printf格式化输出到屏幕上

      ②若定义int x=66;char s[maxn];

   则sprintf(s,“%d”,x);存储的是x的int值66(是两个字符“6”)  若用%c输出,则是66,若用%d输出,则是两个连在一起的字符“6”对应的ASCII码

而sprintf(s."%c",x);存储的则是ASCII为66对应的字符B  若用%c输出,则是B  若用%d输出,则是字符B对应的ASCII码66

     ③strchr函数是用来在一个字符数组s中查找一个字符c,返回首次出现c的位置的指针,返回的地址是字符串在内存中随机分配的地址再加上你所搜索的字符在字符串位置,如果s中不存在c则返回NULL。

   ④%5d表示按照五位数打印,不足五位在前面补空格

      %05d表示按照五位数打印,不足五位在前面补0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: