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

来源:互联网 发布:zeppelin源码分析 编辑:程序博客网 时间:2024/06/05 08:01

原题如下:


L1-025. 正整数A+B

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

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

输入格式:

输入在一行给出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被过滤了


1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 美图m6手机死机怎么办 美图m6s开不了机怎么办 美图手机m6进水怎么办 美图t8摔黑屏怎么办 美图屏幕点不动怎么办 朗动钥匙丢了怎么办 深圳小汽车摇号中签了怎么办 深圳摇号审核通过后怎么办 京东过保修期了怎么办 买的商业预付卡怎么办 壹钱包预付卡金额不足怎么办 美发店换老板原来预付卡怎么办 超市预付卡现超市停业怎么办? 利群购物卡丢了怎么办 利群金卡丢了怎么办 坐飞机洗漱用品超过规定怎么办 请律师团了解后怎么办 三星s9开不了机怎么办 三星手机开不了机了怎么办 安卓手机音响进水了怎么办 音响不读u盘怎么办 虎牌水壶显示f2怎么办 海尔冰箱门关不严没吸力怎么办 忘记京东金融账号怎么办 京东账号手机号已停用怎么办 京东账户忘了怎么办 京东登录名忘了怎么办? 京东已经发货了怎么办 苹果7p黑亮掉漆怎么办 淘宝卖家不肯退运费怎么办 健身付款收据丢了怎么办 收据丢了怎么办能退款 苹果售后不承认基带问题怎么办 电话卡欠费了不用了怎么办 软件移不到sd卡怎么办 手机显示sd卡受损怎么办 美的冰箱出现e6怎么办 美的冰箱显示e6怎么办 冰箱电脑板坏了怎么办 笔记本网线接口坏了怎么办 蓝p吃了一片 怎么办