正整数A+B,附解题思路

正整数A+B


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

输入格式:
输入在一行给出A和B,其间以空格分开。问题是A和B不一定是满足要求的正整数,有时候可能是超出范围的数字、负数、带小数点的实数、甚至是一堆乱码。
注意:我们把输入中出现的第1个空格认为是A和B的分隔。题目保证至少存在一个空格,并且B不是一个空字符串。

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

输入样例1:

123 456

输出样例1:

123 + 456 = 579

输入样例2:

  1. 18

输出样例2:

? + 18 = ?

输入样例3:

-100 blabla bla…33

输出样例3:

? + ? = ?

分析:此题看似简单,实则有很多坑,测试点有很多。除样例1,2,3外,还需考虑

  1. 数字范围问题,[1,1000]范围外也要输出?;(测试点5,6,非正常边界)
  2. 空格问题,B如果是空格,输出?;A是空格,计为0;(题意“并且B不是一个空字符串”)

知识点

切子串:
s1 = s.substr(0, a);     //0为其实下标,a为从下标开始的字符个数

将字符串转化为数字:
n1 = atoi(s1.c_str());

思路:将输入的一行作为一个字符串s,第一个子串为s1,对应数字记为n1(若不是整数或超出范围记为-1);第二个为s2,对应数字记为n2(与n1同理)。第一个空格下标为a,第二个空格下标为b。
首先找空格的下标,若有多个空格,则第一个空格为分割点,故遍历;若存在超过一个空格,标记n2 = -1,若只存在一个空格,则b = s.length()

  for(i = 0;i < s.length();i++)
    {
        if(s[i] == ' ')
        {
            b = i;
            k++;
        }
        if(k >= 2)//有两个空格,无论是B为空格还是B为xxx xx的样式,B都要输出?
         {
             n2 = -1;
             break;
         }
        a = b;
    }
    if(k == 1)//只有一个空格,xxx xxx格式
        b = s.length();

接着,判断两部分子串是否符合要求,若不符合,记n1或n2为-1

    for(i = 0;i < a;i++)
    {
        if(s[i] < '0' || s[i] > '9')
        {
            n1 = -1;
            break;
        }
    }
    for(i = a+1;i < b;i++)
    {
        if(s[i] < '0' || s[i] > '9')
        {
            n2 = -1;
            break;
        }
    }

接下来就可以分情况讨论输出了,在此不单独列出,请看完整AC代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s, s1, s2;
    int n1 = 0, n2 = 0, i, k = 0, a, b;
    getline(cin, s);
    for(i = 0;i < s.length();i++)
    {
        if(s[i] == ' ')
        {
            b = i;
            k++;
        }
        if(k >= 2)//有两个空格,无论是B为空格还是B为xxx xx的样式,B都要输出?
         {
             n2 = -1;
             break;
         }
        a = b;
    }
    if(k == 1)//只有一个空格,xxx xxx格式
        b = s.length();
    for(i = 0;i < a;i++)
    {
        if(s[i] < '0' || s[i] > '9')
        {
            n1 = -1;
            break;
        }
    }
    for(i = a+1;i < b;i++)
    {
        if(s[i] < '0' || s[i] > '9')
        {
            n2 = -1;
            break;
        }
    }
    if(n1 != -1 && n2 != -1)
    {
        s1 = s.substr(0, a);
        s2 = s.substr(a+1, b-a-1);
        n1 = atoi(s1.c_str());
        n2 = atoi(s2.c_str());
        if(n1 >= 1 && n1 <= 1000 && n2 >= 1 && n2 <= 1000)
            printf("%d + %d = %d", n1, n2, n1+n2);
        else if(n1 >= 1 && n1 <= 1000 &&(n2 < 1 || n2 >1000))
            printf("%d + ? = ?", n1);
        else if(n2 >= 1 && n2 <= 1000 &&(n1 < 1 || n1 >1000))
            printf("? + %d = ?", n2);
        else
            printf("? + ? = ?");
    }
    else if(n1 == -1 && n2 != -1)
    {
        s2 = s.substr(a+1, b-a-1);
        n2 = atoi(s2.c_str());
        if(n2 >= 1 && n2 <= 1000)
            printf("? + %d = ?", n2);
        else
            printf("? + ? = ?");
    }
    else if(n1 != -1 && n2 == -1)
    {
        s1 = s.substr(0, a);
        n1 = atoi(s1.c_str());
        if(n1 >= 1 && n1 <= 1000)
            printf("%d + ? = ?", n1);
        else
            printf("? + ? = ?");
    }
    else
        printf("? + ? = ?");
    return 0;
//数字范围问题,测试点5,6,非正常边界测试
//0 2,测试点5
}
  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 题目描述: 给定两个在 D 进制下的数 A 和 B,请计算 A + B 的值,并以 D 进制输出。 输入格式: 输入在一行中依次给出 3 个整数 A、B 和 D(1 < D ≤ 10),其中 A 和 B 是不超过 10^100位的正整数。 输出格式: 输出 A + B 的值,以 D 进制输出。 输入样例: 123 456 8 输出样例: 1103 解题思路: 本题需要将两个 D 进制下的数 A 和 B 相加,然后再将结果转换为 D 进制输出。因此,我们可以先将 A 和 B 转换为十进制,然后再将结果转换为 D 进制输出。 具体实现时,我们可以使用字符串读入 A 和 B,然后将其转换为十进制数。接着,我们将两个十进制数相加,得到结果后,再将其转换为 D 进制输出即可。 代码实现: ### 回答2: 自从降临地球的外星人爱数学(Alien Loves Mathematics)来到我们这个星球后,数学世界里发生了许多奇妙的事件。今天,我们就来看一下,Alien玩游戏时遇到的问题:1022 d 进制的 a b 等于多少? 首先,我们需要了解一下十进制和其他进制的转换方法。以十进制和二进制为例,十进制数 18 可以转换为二进制数 10010,转换的方法是将十进制数不断除以 2,直到商为 0,然后把余数倒序排列在一起即可。 但在 Alien 的星球上,他们使用的是 1022 进制。与十进制不同的是,它们没有数字 0,因此从 1 到 1021,一共有 1021 个不同的数字。而当超过 1021 时,就需要进位,进位后的数字是两位数。 接下来我们来看如何将一个十进制数转换为 1022 进制。依据进制的转化原理,我们可以一直将一个十进制数不断除以 1022,直到商为 0。这时我们把每次的余数倒序排列在一起,得到的就是这个数的 1022 进制表示方式。 例如,如果我们要把十进制数 123456 转换为 1022 进制,我们按照上述方法可以得到:123456 ÷ 1022 = 120 余 136,120 ÷ 1022 = 0 余 120,因此将这两次余数倒序排列在一起,就得到了 123456 的 1022 进制表示方式:120136。 回到本题,我们需要求解的是 1022 进制下的 a b 相加之和。以题目中给出的例子,a 和 b 分别为 211 和 906,我们可以将它们转换为十进制,相加之和得到 1117,最后再将 1117 转换为 1022 进制即为答案。具体实现过程可见下面的代码。 ``` def convert_to_1022(decimal): result = '' while decimal > 0: decimal, remainder = divmod(decimal, 1022) result = str(remainder) + result return result a = 211 b = 906 decimal_sum = a + b answer = convert_to_1022(decimal_sum) print(answer) ``` 在上面的代码中,convert_to_1022 函数接收一个十进制数 decimal 作为参数,返回该数的 1022 进制表示方式。在主程序中,我们将 a 和 b 转换为十进制相加之和,得到 decimal_sum,然后将 decimal_sum 转换为 1022 进制,最后打印结果。在本题中,程序输出的结果为 1006。 总之,要解决这道题目,我们需要理解 1022 进制的定义和转换方法,然后再将 a b 转换为十进制相加,最后将结果转换为 1022 进制即可。 ### 回答3: 题目简述 本题需要求解在1022进制下的两个数a和b,满足等式a * b = 6ED 。其中,a、b分别为三位数。 解题思路 首先要明确1022进制是什么意思。其实,它就是另一种十进制。我们平时所使用的十进制是以0~9这十个数为基础的,而1022进制是以0~9、A~P这20个数为基础的一种进制。接下来我们在这个进制下逐步求解。 首先,我们将6ED转化为十进制,计算得到6ED的十进制值为:1773。接着,我们将1773分解质因数,可以得到: 1773 = 3 * 3 * 197 将197转换为1022进制,得到554。此时,等式就变成了: a * b = 3 * 3 * 554 由于a、b均为三位数,可以列出以下方程组: a = 3 * x b = 3 * y * 554 其中,x、y都是三位数。将上述方程代入a * b = 3 * 3 * 554中,最终得到: x * y = 554 继续将554分解质因数,并将每个质因数转换为1022进制,得到: 554 = 2 * 277 将277转换为1022进制,得到7F。因此,x和y的值分别为2F0和7F0。最终得出两个符合条件的数:a = 3 * 2F0 = 7E4,b = 3 * 7F0 * 554 = 1C38350。这两个数转换为十进制后,分别为:32356和4723408。 结论 在1022进制下,两个三位数a、b,使得a * b = 6ED成立的解为:a = 32356,b = 4723408。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值