A+B专题分析
A+B问题是acm编程的基础,基石,虽说是基础,是简单题,但其实并不简单,为什么呢?因为它的要求正是对acm编程的基础要求,只有这个能做的熟练,那么,后边牵扯到相应一些格式要求,甚至一些算法思想都将不是问题。
下面,我将对其就我个人理解进行一下分析总结。
首先,刚接触的最简单的A+B类型就是很直接的直接输出,如下例:
#include <stdio.h>
int main()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF)//实现多组数据输入
{
printf("%d\n",a+b);//也可以在定义一个变量,但个人认为这样看起来简洁,
}
Return 0;
}
像这种最简单的其实对于从未接触过的我来说,也费了一番周折首先,是保证多组数据输入,这个对我来说是新知识:它是以csanf结束符作为判断依据的并将其作为while判断条件,已达到对整个main函数的操控,就好比给主公加了个束缚,谏官的职责来对主上进行一定的约束,以使其更好为我们所用。
再深入一点就可以加一些结束标志,比如对某一个值的值:
#include <stdio.h>
int main()
{
int a,b;
while(scanf("%d",&a,&b)!=EOF&&a!=0)
{
scanf("%d%d",&a,&b);
printf("%d\n",a+b);
}
Return 0;
}
这里不仅仅是简单只有A+B了,而是有了对a的判断,当a不为0是才执行,这里还有一种表达方法就是while(scanf(“%d%d”,&a,&b)!=EOF&&a);当然也可以以多个值比如....&&a&&b;就是以a,b都为零作为结束的。那么这就是简单的两个数相加,接下来看一下连加的情况:
#include <stdio.h>
int main()
{
int a,b,sum=0,i;
while(scanf("%d",&a)!=EOF&&a)
{
for(i=0;i<a;i++)
{
scanf("%d",&b);
sum+=b;
}
printf("%d\n",sum);
sum=0;//加和类,或其他需要保持初值的 记得用完后一定赋初值;
}
Return 0;
}
这里就不单单是两数加和了,而是连加,并以a==0为结束,这里需要注意初始化,此例中我是用过后又重新赋值,当然也可以在用前进行初始化这样就不用多写这一行了,诚然这已经不错,但是并不是任何时候我们都希望以一个特殊值作为结束的,那么有没有一按回车就出答案,而且没有结束特殊值的呢,,一个偶然机会我找到了,其实也不能说是偶然,因为是在学习书本知识时发现的,下面给一下:
#include <iostream>
#include <string>
#include <sstream>//调用stringstream
using namespace std;
int main()
{
string line;
while(getline(cin,line))//用getline读取输入的 字符串流
{
int sum = 0,x;
stringstream ss(line);//创建新的字符串流 ss 来存储输入的流;
while(ss >> x)//读取字符串流中的 整数x
sum += x;//进行加和
cout << sum << "\n";//输出结果;
}
return 0;
}
这其中我已加了不少注释,就不做详细分析了(因为注释中已经有了吗),那么介绍了这么多,其实真正以应该重视的才要出现,就是格式控制,有人会说,这很容易啊!前面不才是重要吗!其实前面的倒好说 基本没问题因为那都是一些理解了就很容易写出的,可是格式控制贯穿整个acm编程,我们随时随地都会见到,而且很容易出错,变化相对也不少,所以应该引起重视。不可轻敌。常见的有答案间输出空行(答案间),空格,开头结尾就不能有:
#include <stdio.h>
int main()
{
int a,b,c,sum=0,i,j;
while(scanf("%d",&a)!=EOF&&a)//输入一个数表示有多少组数需要计算,以0作为结束标志;
{
for(i=0;i<a;i++)
{
scanf("%d",&b);//每组数有b个数要相加;
for(j=0;j<b;j++)
{
scanf("%d",&c);
sum+=c;//用sum表示数据的和;
}
printf("%d\n",sum);
if(i<a-1)/*加一个条件判断,加上空行,空格也类似,这样在最后一个答案就不会有多余空行输出了,。那么空格(空行)只有这种写法???怎么可能??种类繁多啊!来举个例子:先定义一个变量 k=b;if(k)printf("\n");printf("%d\n",sum,k++);怎样是不是感觉简洁了一些呢!注意一个问题(k++要放后边 不然就要输出k的值了);*/
printf("\n");
sum=0;//记得在每组数计算完成后 要对sum清零!!!!!这里很好理解 却经常会忘掉!!!!切记;
}
}
}
这是在多数相加基础上做了延伸,然后又加了格式控制的介绍,分析,例中使用一个条件判断输出空行的,其实还有简单的方法,就是将最后一个单独输出(这里说的简单是看起来而写的行数却不少,因为还是要判断何时是最后一个啊!)那就是
If(i<a-1)
printf(“%d\n\n”,sum);
else
Printf(“%d\n”,sum);
这样其实就书写来说并不少,但容易看懂,好理解。所以我说简单。还有就是我在注释中写的,当然这些都是个人见到的进行总结,可能并不完备,也可能说得并不清楚,不明白,但我会继续努力的,当我有能力之时,定将精细制作。
那说了这么多,A+B类型其实已经差不多了,只是还有一些拓展了,比如当数据超出各种类型,那要怎么办呢!当时我第一反应是数组,确实被我蒙对了,但写着并不那么轻松(至少我当时费了不少劲,可能是基础太差吧!但那又有什么关系呢?只要敢做 总有一天会克服的) 用数组来写,如下:
#include <stdio.h>
#include <string.h>
char a[1110000];
char b[1110000];
int aa[1110000];
int bb[1110000];
int max(int x,int y)//求两者中大的数
{
int m;
if(x>=y)
{
m=x;
}
else
{
m=y;
}
return m;
}
int main()
{
int i,j,k,n;
while (scanf("%d",&n)!=EOF)
{
for(k=1;k<=n;k++)
{
scanf("%s %s",a,b);
memset(aa,0,sizeof(aa));
memset(bb,0,sizeof(bb));//使用前先清空 是个好习惯
for(j=0,i=strlen(a)-1;i>=0;i--,j++)
aa[j]=a[i]-'0';//将字符型转为数字,同时倒叙;
for(j=0,i=strlen(b)-1;i>=0;i--,j++)
bb[j]=b[i]-'0';
for(i=0;i<max(strlen(a),strlen(b));i++)//需要将所有数加上 故取长的那一个作为依据
{
aa[i]=aa[i]+bb[i];将和的结果放在aa里;
if(aa[i]>=10)//判断是否需要进位;
{
aa[i]%=10;
aa[i+1]+=1;
}
}
printf("Case %d:\n",k);
printf("%s + %s = ",a,b);
if(aa[max(strlen(a),strlen(b))]==0)//判断结果是否会多出一位
for(i=max(strlen(a),strlen(b))-1;i>=0;i--)
{
printf("%d",aa[i]);
}
else
for(i=max(strlen(a),strlen(b));i>=0;i--)//与上一个for不同,此有最高位输出。
{
printf("%d",aa[i]);//依次输出;
}
printf("\n");
if(k<n)
printf("\n");
}
}
}
这里用的思想就是手算时的思想,倒叙相加,逢十进位思想(这不是我说的,是老师,学长说的,我总结),就是输入字符串形式,再倒叙转化为int型(当然是逐位转化),然后相加,判断是否需要进位,最后再倒叙依次输出(此时就是所需结果了),这里还有一个问题就是结果可能比原来数组多一位(因为进位),例子中已经有判断。
然后,这就接近尾声了,在做一个关于进制转化的基础加法题:
#include <stdio.h>
int main()
{
int a,b;
while(scanf("%x %x",&a,&b)!=EOF)
printf("%d\n",a+b);
return 0;
}
就是输入两个16进制数,相加后以10进制输出,这里用到了强制类型转换,然后要做类似于前面的 连加,什么的,就可以模仿写出了。
本次,介绍到此结束。
谢谢!!!
A+B问题在ACM编程中至关重要,本文深入剖析了基础的A+B问题,从简单的直接相加到处理多组数据、格式控制及进位计算等复杂情况,探讨了如何运用C语言解决这些问题,并引入了字符串流和进制转换的概念。通过实例解析,强调了格式控制在整个编程过程中的重要性。
3430

被折叠的 条评论
为什么被折叠?



