您的位置:首页 > 其它

团体程序设计天梯赛-练习集 L1-025. 正整数A+B

2017-03-23 14:19 344 查看
原题如下:


L1-025. 正整数A+B

时间限制

400 ms

内存限制

65536 kB

代码长度限制

8000 B

判题程序

Standard

作者

陈越

本题的目标很简单,就是求两个正整数A和B的和,其中A和B都在区间[1,1000]。稍微有点麻烦的是,输入并不保证是两个正整数。

输入格式:[/b]

输入在一行给出A和B,其间以空格分开。问题是A和B不一定是满足要求的正整数,有时候可能是超出范围的数字、负数、带小数点的实数、甚至是一堆乱码。

注意:我们把输入中出现的第1个空格认为是A和B的分隔。题目保证至少存在一个空格,并且B不是一个空字符串。

输出格式:

如果输入的确是两个正整数,则按格式“A + B = 和”输出。如果某个输入不合要求,则在相应位置输出“?”,显然此时和也是“?”。
输入样例1:
123 456

输出样例1:
123 + 456 = 579

输入样例2:
22. 18

输出样例2:
? + 18 = ?

输入样例3:
-100 blabla bla...33

输出样例3:
? + ? = ?


不妨我再给这道题多几个输入输出样例

输入样例4:

22 22 22

输出样例4:
22 + ? = ?

输入样例5:
1 1234

输出样例5:
1 + ? = ?

输入样例6:
0 123

输出样例6:
? + 123 = ?


通过上述几个笔者增加的输入输出样例,估计得不了满分的同学应该知道需要考虑些什么边界条件了吧。  题目中要求我们注意:我们把输入中出现的第1个空格认为是A和B的分隔。也就是说B中的空格数可无法保证。

有了这些理解,笔者首先写出了如下代码:

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
using namespace std;
int main()
{
char a[1000],b[1000];
cin>>a;
getchar();
gets(b);

int A,B,i,len1,len2,temp1=0,temp2=0,num[1000];
len1=strlen(a);
len2=strlen(b);
for(i=0; i<len1; i++)
{
if(a[i]-48>=0&&a[i]-48<=9)
{
temp1++;
}
}
for(i=0; i<len2; i++)
{
if(b[i]-48>=0&&b[i]-48<=9)
{
temp2++;
}
}
A=temp1==len1;
B=temp2==len2;

if(A&&B)
{
int C=atoi(a)>=1&&atoi(a)<=1000;
int D=atoi(b)>=1&&atoi(b)<=1000;
if(C&&D)
cout<<a<<" + "<<b<<" = "<<atoi(a)+atoi(b)<<endl;
else if(C&&!D)
cout<<a<<" + "<<"? = ?"<<endl;
else if(!C&&D)
cout<<"? + "<<b<<" = ?"<<endl;
else
cout<<"? + ? = ?"<<endl;
}
else if(A&&!B)
{
cout<<a<<" + "<<"? ="<<" ?"<<endl;
}
else if(!A&&B)
cout<<"? "<<"+ "<<b<<" = ?"<<endl;
else
cout<<"? + ? = ?"<<endl;
}

大体需要50行,而且这方法看起来着实笨重,不符合我们追求的代码风骚的要求,这时,笔者想到了C的一个库函数sscanf();用它来处理这道题就游刃有余了,先给出笔者的代码:
#include "bits/stdc++.h"
using namespace std;
int main()
{
char a[99999],b[99999],atemp[99999],btemp[99999];
scanf("%s",a);
getchar();
gets(b);
sscanf(a,"%[0-9]",atemp);
sscanf(b,"%[0-9]",btemp);
if(strlen(a)>strlen(atemp)&&strlen(b)>strlen(btemp)||!(atoi(a)>=1&&atoi(a)<=1000)&&!(atoi(b)>=1&&atoi(b)<=1000))
{
cout<<"? + ? = ?"<<endl;
}
else if(strlen(a)>strlen(atemp)||!(atoi(a)>=1&&atoi(a)<=1000))
{
cout<<"? + "<<b<<" = ?"<<endl;
}
else if(strlen(b)>strlen(btemp)||!(atoi(b)>=1&&atoi(b)<=1000))
{
cout<<a<<" + ?"<<" = ?"<<endl;
}
else
{
cout<<a<<" + "<<b<<" = "<<atoi(a)+atoi(b)<<endl;
}
}

顿时压缩到了30行以内思路显得十分清晰,对于这道题,我们要判断的,首先是是a和b是不是个非负整数,也就是a和b中除了0-9这些数字是否存在其他字符,若有,直接pass掉这个数,若没有,则这个数已经是非负整数,由题意我们又知道a和b必须保证在[1,1000]内,故需要进行二重判断,理论上2*2=4种情况,笔者就分了4中情况;

附:关于sscanf()这个函数的用法,做如下解释:

sscanf() - 从一个字符串中读进与指定格式相符的数据.

  函数原型:

  int sscanf( string str, string fmt, mixed var1, mixed var2 ... );

  int scanf( const char *format [,argument]... );

  说明:

  sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。

  其中的format可以是一个或多个 {%[*] [width] [{h | l | I64 | L}]type | ' ' | '\t' | '\n' | 非%符号}

  注:

  1、 * 亦可用于格式中, (即 %*d 和 %*s) 加了星号 (*) 表示跳过此数据不读入. (也就是不把此数据读入参数中)

  2、{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。

  3、width表示读取宽度。

  4、{h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。

  5、type :这就很多了,就是%s,%d之类。

  6、特别的:%*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值

  支持集合操作:

  %[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)

  %[aB'] 匹配a、B、'中一员,贪婪性

  %[^a] 匹配非a的任意字符,贪婪性

注意:在读入的字符串是空字符串时,sscanf函数并不改变待读入到的字符串的值。

例子:

  1. 常见用法。

  char buf[512] = ;

  sscanf("123456 ", "%s", buf);

  printf("%s\n", buf);

  结果为:123456

  2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。

  sscanf("123456 ", "%4s", buf);

  printf("%s\n", buf);

  结果为:1234

  3. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。

  sscanf("123456 abcdedf", "%[^ ]", buf);

  printf("%s\n", buf);

  结果为:123456

  4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。

  sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);

  printf("%s\n", buf);

  结果为:123456abcdedf

  5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。

  sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);

  printf("%s\n", buf);

  结果为:123456abcdedf

  6、给定一个字符串iios/12DDWDFF@122,获取 / 和 @ 之间的字符串,先将 "iios/"过滤掉,再将非'@'的一串内容送到buf中

  sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);

  printf("%s\n", buf);

  结果为:12DDWDFF

  7、给定一个字符串““hello, world”,仅保留world。(注意:“,”之后有一空格)

  sscanf(“hello, world”, "%*s%s", buf);

  printf("%s\n", buf);

  结果为:world

  %*s表示第一个匹配到的%s被过滤掉,即hello被过滤了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: