PTA L1-025正整数A+B

PTA L1-025正整数A+B

题目链接

  • 难点
    此题说难难,说不难又难,不难在于其算法思想非常简单。难在考虑特殊情况的细致程度要求很高,一般不会让你一次性AC,总有那么几个点会卡你几下,除非你是一个非常细致的人。以下列出一些特殊情况:

1.有0出现,你需要判为?

2.有大于1000的数字出现,你需要判为?

3.这是本题最难的点,A可以为空串!

对于第3个点,我们要如何处理呢?我们首先要选择好的方法,此题一般解法是定义两个字符串来处理,如果是这样,那么处理第3个难点会变得困难而且复杂,所以好的方法很重要。与其判定两个串,倒不如一次性判定一个串,而且题目已经给出两个串的界线——第一个碰到的空格,既然如此,何不利用一发?C++语言提供了可以接受字符串的语句getline,用它接受一个串,寻找第一个碰到的空格,往前判定A,往后判定B,如果第一个字符为空格,那么A需要判为?

作者:qq_37729102
来源:优快云
原文:https://blog.youkuaiyun.com/qq_37729102/article/details/80716264

#include<iostream>
#include<string>
using namespace std;
int main()
{
	string S;
	int flagA = 0, flagB = 0;
	getline(cin,S);//使用getline来接收包括空格在内的字符 
	int sumA = 0, sumB = 0, Base;
	for (int i =0; i <S.length(); i++)
	{
		if(S[i]==' ')//碰到第一个空格 
		{
			Base = 1;//初始化 
			for(int j=i-1;j>=0;j--)//计算A,注意j的范围从前一个字符到0
			{
				if (S[j]<'0' || S[j]>'9')//如果字符不为数字 
				{
					flagA = 1;
					break;//标识,退出 
				}
				else
				{
					sumA += Base*(S[j] - '0');//如果为数字,累加 
					Base *= 10;
				}
				if(i==0)//如果第一个字符是空格 
				{
					flagA=1;
					break;//标识,退出 
				}
			}
			if (sumA>1000||sumA==0)//如果累加和不在0到1000范围内 
			flagA = 1;
			Base = 1;//注意重新初始化 
			for(int j=S.length()-1;j>i;j--)//计算B,注意j的范围从最后一个字符到i+1 
			{
				if (S[j]<'0' || S[j]>'9')
				{
					flagB = 1;
					break;
				}
				else
				{
					sumB += Base*(S[j] - '0');
					Base *= 10;
				}
			}
			if (sumB>1000||sumB==0)
			flagB = 1;
			break;//注意及时跳出大循环 
		}	
	}
	if (flagA)
	{
		if (flagB)
			cout << "? + ? = ?";
		else
			cout << "? + " << sumB << " = ?";
	}
	else
	{
		if (!flagB)
			cout << sumA << " + " << sumB << " = " << sumA + sumB;
		else
			cout << sumA << " + ? = ?";
	}
	return 0;
}

<think>好的,我现在需要解决PTA平台上的L1-025题“正整数A+B”的问题。首先,我得仔细理解题目要求。题目大意是输入两个正整数A和B,但可能存在格式错误的情况,需要正确判断并输出结果。如果输入不符合要求,对应的数字用问号代替,结果也是问号。 根据用户提供的引用内容,尤其是引用[1]、[3]、[4],可以看到不同的解题方法。比如引用[1]中用split()分割输入,然后使用isdecimal()判断是否是正整数。但要注意的是,split()可能在输入中有多个空格时分割不正确,因为题目中的分隔符应该是一个空格,所以需要正确处理这种情况。 引用[4]提到处理输入时需要注意第一个空格作为分隔符,后面的内容作为B。例如,输入可能包含多个空格或者没有空格,这时候需要找到第一个空格的位置来分割A和B。因此,正确的做法应该是读取整个输入字符串,找到第一个空格的位置,将前面的部分作为A,后面的作为B。如果输入中没有空格或者第一个字符就是空格,那么A或B无效。 接下来,我需要确定如何判断一个字符串是否为有效的正整数。根据题目,正整数的范围是11000,所以不仅要检查字符串是否全为数字,还要检查转换后的数值是否在范围内。例如,字符串“0123”虽然全为数字,但可能不符合要求,因为前导零的存在。不过题目中是否允许前导零呢?根据常规的题目设定,通常正整数不允许前导零,所以需要额外判断这一点。 现在,我需要处理输入的分割问题。例如,输入可能像“123 456”,此时正确分割为A=123,B=456。但如果输入是“123 456”(多个空格),split()方法可能分割成['123', '', '456'],这样直接取第一个和第二个元素会出错。因此,正确的做法应该是找到第一个空格的位置,分割成两个部分,不管后面是否有多个空格。 例如,在Python中,可以用find(' ')来定位第一个空格的位置,然后切片处理。例如: s = input().strip() space_pos = s.find(' ') if space_pos == -1: # 没有找到空格,A或B无效 A = s B = '' else: A = s[:space_pos] B = s[space_pos+1:].lstrip() # 这里可能需要处理后面还有空格的情况? 不过根据引用[4],题目中的分隔符是第一个空格,后面的内容都属于B,包括后面的空格。例如输入“123 45 6”,那么A是“123”,B是“45 6”。这时候B包含空格,显然不是有效数字。所以处理的时候应该只取第一个空格前的部分作为A,第一个空格后的全部内容作为B,不需要考虑后面的空格。但B本身需要符合正整数的条件,即整个字符串都是数字且数值在1~1000之间。 接下来,对A和B分别进行验证: 1. 检查字符串是否为空。 2. 检查是否全为数字字符。 3. 转换后数值是否在11000之间。 4. 是否有前导零(例如“012”是否合法)? 例如,对于字符串“0”,是否有效?题目要求是正整数,所以0不属于有效范围。因此,当字符串转成整数后必须满足1 ≤ num ≤ 1000,并且字符串本身不能以0开头,除非数字本身就是0,但0不符合条件,所以任何以0开头的数字字符串(长度大于1)都是无效的。例如,“012”是无效的,“0”也是无效的。 因此,判断逻辑应该是: 对于字符串s: - 如果s为空 → 无效。 - 如果s不是全数字 → 无效。 - 否则,转换为整数num: - 如果num <1 或 num >1000 → 无效。 - 另外,如果s的长度大于1且以'0'开头 → 无效。 例如: - '123' → 有效。 - '012' → 无效(前导零)。 - '0' → 无效(数值为0)。 - '1001' → 无效(超过1000)。 - '1a' → 无效(非全数字)。 这样,判断函数可以写成: def is_valid(s): if not s: return False if not s.isdigit(): return False if len(s) > 1 and s[0] == '0': return False num = int(s) if 1 <= num <= 1000: return True else: return False 然后,分割输入字符串为A和B: 输入整个字符串,找到第一个空格的位置。如果没有空格,那么A和B至少有一个无效。如果有多个空格,分割后的B可能包含后续的空格,但此时B的字符串可能包含非数字字符,所以会被判断为无效。 例如,输入“123 45”,分割后A是“123”,B是“ 45”(注意B前面有一个空格),此时B的字符串是“ 45”,包含空格,所以is_valid返回False。 或者,在分割的时候,应该将B部分去掉前面的空格吗?比如,原题中的输入是否允许B前面有空格?比如,输入“123 456”,正确的分割应该是A为“123”,B为“456”?或者原题中要求输入的两个数之间只能有一个空格? 根据题目的输入格式描述,可能题目中的输入是两个正整数,中间由一个空格分隔。所以,正确的输入应该是一个空格分隔的两个字符串。但实际测试中可能存在多个空格的情况,这时候需要严格按照第一个空格分割,不管后面的空格如何。 例如,输入“123 456”,分割后A是“123”,B是“ 456”(包含前面的空格),所以B的字符串是“ 456”,这时候B的is_valid检查会因为前面的空格而返回False,因为字符串中有非数字字符。 因此,正确的分割应该是将A作为第一个空格前的部分,B作为第一个空格后的所有字符(包括可能存在的空格),然后分别去除前后的空格?或者原题中的输入是否存在前导或后置空格? 可能题目中的输入是保证两个数由一个空格分隔,但实际测试点可能输入有其他情况,比如多个空格,或者没有空格,或者前面后面有空格。因此,正确的处理应该是: 输入的字符串可能包含前导或后置空格,所以需要先strip()处理整个输入吗?或者题目中的输入数据不会包含前导或后置空格? 例如,引用[1]中的代码是直接split(),这样如果输入有多个空格,split()会分割出多个部分,比如输入“123 45”会被分割成['123', '45'],而split()默认分割任意多个空格。但题目中的正确输入应该是一个空格,但其他情况可能被视为无效。例如,输入中有多个空格的情况下,split()得到的结果可能错误,因为题目要求第一个空格作为分隔符,后面的内容属于B,可能包含空格。因此,split()方法可能不适用,因为split()会合并多个空格,导致分割错误。 例如,输入“12 3 45”,正确的分割是A=“12”,B=“3 45”,这时候B包含空格,因此无效。此时,使用split()得到的是['12', '3', '45'],A和B会被取为第一个和第二个元素,但正确的B应该是“3 45”,因此split()方法无法正确处理这种情况。 所以,正确的分割方法应该是找到第一个空格的位置,将前面的部分作为A,后面的所有字符作为B,不管后面是否有多个空格。例如: s = input().strip() space_pos = s.find(' ') if space_pos == -1: A = s B = '' else: A = s[:space_pos] B = s[space_pos+1:] 这样,无论后面有多少空格,B都包含第一个空格后的所有内容。例如,输入“123 456”,A是“123”,B是“456”;输入“123 456”,A是“123”,B是“ 456”(此时B以空格开头,会被判断为无效);输入“123 45 6”,则B是“45 6”,同样无效。 因此,正确的处理方法是先找到第一个空格的位置,分割A和B,然后对A和B进行有效性判断。 接下来,编写代码的大致步骤: 1. 读取输入,去除前后空格。 2. 查找第一个空格的位置,分割A和B。 3. 判断A是否有效: a. 是否为空字符串。 b. 是否全为数字。 c. 是否在1~1000之间。 d. 是否有前导零(长度大于1时)。 4. 同样判断B是否有效。 5. 根据A和B的有效性输出结果。 例如,在引用[3]的代码中,作者处理输入的方式是遍历字符直到找到第一个空格,然后将前面部分作为A,后面作为B。这可能更准确。例如: arr = input().strip() s = ['', ''] c = 0 for i in arr: if i != ' ': s[0] += i c +=1 else: break s[1] = arr[c+1:].lstrip() # 这里是否应该去除后面的空格?或者原样保留? 但原题中,可能B的字符串中如果有空格,则B无效。所以,B的字符串中是否包含空格会影响判断。例如,B是“45 6”,则is_valid会返回False。 因此,正确的做法是将B原样保留,不需要处理后面的空格,直接判断整个字符串是否为有效正整数。 现在,编写代码: 读取输入,分割成A和B: s = input().strip() space_pos = s.find(' ') if space_pos == -1: A = s B = '' else: A = s[:space_pos] B = s[space_pos+1:] 然后定义有效性检查函数: def is_valid(num_str): if not num_str: return False if not num_str.isdigit(): return False if len(num_str) > 1 and num_str[0] == '0': return False num = int(num_str) return 1 <= num <= 1000 然后检查A和B的有效性: valid_a = is_valid(A) valid_b = is_valid(B) 然后根据情况输出: if valid_a and valid_b: print(f"{A} + {B} = {int(A)+int(B)}") elif valid_a and not valid_b: print(f"{A} + ? = ?") elif not valid_a and valid_b: print(f"? + {B} = ?") else: print("? + ? = ?") 但需要注意,当A或B无效时,输出中的问号替换对应的部分。例如,如果A有效,B无效,则输出“A + ? = ?”。 现在,测试几个案例: 测试案例1: 输入:123 456 A是“123”,有效;B是“456”,有效。输出123 + 456 = 579。 测试案例2: 输入:012 456 A是“012”,无效(前导零且长度>1);B是“456”,有效。输出? + 456 = ?. 测试案例3: 输入:123 45 6 → 分割后A是“123”,B是“45 6”,B包含空格,无效。输出“123 + ? = ?”。 测试案例4: 输入:0 99 → A是“0”,无效(数值为0);B是“99”,有效。输出? + 99 = ?. 测试案例5: 输入:1001 999 → A是“1001”,无效(超过1000);B是“999”,有效。输出? + 999 = ?. 测试案例6: 输入:123(无空格) → A是“123”,有效;B是空字符串,无效。输出“123 + ? = ?”. 测试案例7: 输入: 123 456(前后空格) → 处理后s.strip()是“123 456”,分割后A是“123”,B是“ 456”,B包含空格,无效。输出“123 + ? = ?”. 这样处理是正确的吗? 例如,输入“ 123 456 ”,strip()后变成“123 456”,分割正确。 另一个情况,输入是“ 12 3 45”,分割后A是“12”,B是“3 45”,B包含空格,无效。输出“12 + ? = ?”。 这样代码就能正确处理这些情况了。 现在,综合这些步骤,可以写出正确的Python代码。需要注意的是,输入的处理必须正确分割A和B,以及有效性检查要包括前导零和数值范围。 现在参考用户提供的引用中的代码,比如引用[1]中的代码可能存在问题,因为它使用split(),这在输入有多个空格时无法正确分割。例如输入“123 456”会被split()分割成['123', '456'],而正确的分割应该是A=“123”,B=“ 456”(包含空格),导致B无效。但split()分割后,B被取为“456”,从而可能错误地判断为有效。因此,split()方法不适用于此题的正确解法,必须使用找到第一个空格的位置来分割。 例如,引用[1]中的代码: A,B = input().split() 这样在输入有多个空格时会报错,因为split()默认按任意空格分割,分割后的列表可能超过两个元素,导致无法解包给A和B。比如输入“12 34 56”会报ValueError。所以正确的做法应该是先读取整个字符串,找到第一个空格的位置,而不是用split()。 引用[3]中的代码处理输入的方式是遍历每个字符,直到找到第一个空格,然后将前面的作为A,剩下的作为B。例如: arr=input() s=['',''] c=0 for i in arr: if i!=' ': s[0]+=i c+=1 else: break s[1]=arr[c+1:] 这种方法可以正确分割出第一个空格前的部分作为A,后面的所有字符作为B,不管是否有多个空格。例如,输入“123 456”会得到A=“123”,B=“456”;输入“123 456”得到A=“123”,B=“ 456”(此时B以空格开头,无法通过is_valid检查)。 这样处理是正确的,所以引用[3]中的代码在处理输入分割上是正确的。 因此,正确的Python代码应该按照这种分割方式,然后进行有效性检查。 现在,综合所有分析,写出正确的代码: 步骤: 1. 读取输入并去除前后空格(可能题目中的测试用例包含前后空格?) 比如,输入可能有前导或后置空格,所以应该先strip(),例如: s = input().strip() 然后处理分割: space_pos = s.find(' ') 如果space_pos为-1,说明没有空格,A是整个字符串,B为空。 否则,A是s[:space_pos],B是s[space_pos+1:]。 但是,s在strip()之后,前后没有空格,所以分割后的A和B不会有前导或后置空格吗?例如,输入是“ 123 456 ”,strip()后变成“123 456”,分割正确。如果输入是“123 456”,分割后A是“123”,B是“ 456”(中间有两个空格),此时B字符串是“ 456”,包含空格,导致无效。 但是,题目中的输入是否允许这样的情况?比如,题目要求输入是两个正整数,中间由一个空格分隔,所以正确的输入不会有多个空格。但测试点可能会包含这些情况,因此需要处理。 接下来,编写有效性检查函数: def is_valid(num_str): # 检查是否为空 if not num_str: return False # 检查是否全为数字 if not num_str.isdigit(): return False # 检查前导零 if len(num_str) > 1 and num_str[0] == '0': return False # 转换为数值检查范围 num = int(num_str) if 1 <= num <= 1000: return True return False 然后,分割后的A和B进行有效性判断: valid_A = is_valid(A) valid_B = is_valid(B) 最后根据情况输出: if valid_A and valid_B: print(f"{A} + {B} = {int(A)+int(B)}") elif valid_A and not valid_B: print(f"{A} + ? = ?") elif not valid_A and valid_B: print(f"? + {B} = ?") else: print("? + ? = ?") 现在,处理一些特殊情况: 比如,输入是空字符串,经过strip()后变成空,此时A和B均为空,输出“? + ? = ?”。 输入是“0 123”,A是“0”,判断为无效(数值为0),B是“123”,有效。输出“? + 123 = ?”。 输入是“0123 456”,A是“0123”,无效(前导零),输出“? + 456 = ?”。 输入是“123 0456”,B是“0456”,无效,输出“123 + ? = ?”。 现在,将这些逻辑整合到代码中: 完整代码: s = input().strip() space_pos = s.find(' ') if space_pos == -1: A = s B = '' else: A = s[:space_pos] B = s[space_pos+1:] def is_valid(num_str): if not num_str: return False if not num_str.isdigit(): return False if len(num_str) > 1 and num_str[0] == '0': return False num = int(num_str) return 1 <= num <= 1000 valid_A = is_valid(A) valid_B = is_valid(B) if valid_A and valid_B: print(f"{A} + {B} = {int(A)+int(B)}") elif valid_A and not valid_B: print(f"{A} + ? = ?") elif not valid_A and valid_B: print(f"? + {B} = ?") else: print("? + ? = ?") 这样应该可以正确处理各种情况。需要注意的是,当B分割后可能包含空格,此时B的字符串包含非数字字符,is_valid会返回False。 例如,输入是“123 45 6”,分割后B是“45 6”,包含空格,所以is_valid(B)返回False,输出“123 + ? = ?”。 另一个测试案例: 输入是“ 12a3 456”,strip()后是“12a3 456”,分割后A是“12a3”,B是“456”。A的字符串包含字母a,所以is_valid(A)返回False,B有效。输出“? + 456 = ?”。 现在,检查引用中的代码是否正确。例如,引用[3]中的代码: 他们的处理方式是遍历每个字符直到遇到空格,将前面部分作为A,剩下的作为B。例如: arr=input() s=['',''] c=0 for i in arr: if i!=' ': s[0]+=i c+=1 else: break s[1]=arr[c+1:] 这与我上面的分割方式类似,不过没有处理输入前后的空格,因此可能需要先strip()吗?比如,输入“ 123 456”会被分割成A=' 123',这会导致A无效。因此,正确的做法是先将输入strip(),去除前后空格,然后再分割。 因此,在我的代码中,加入了s = input().strip(),这可以处理输入前后有空格的情况。例如,输入“ 123 456 ”会被处理成“123 456”,正确分割。 因此,正确的代码应该先strip()输入字符串,然后进行分割。 现在,验证代码是否正确处理各种情况: 测试案例: 1. 输入:“123 456” → 输出“123 + 456 = 579” ✔️ 2. 输入:“123 456” → 分割后B是“ 456”,包含空格 → B无效 → 输出“123 + ? = ?” ✔️ 3. 输入:“12 3” → 分割后B是“3” → 有效 → 输出“12 + 3 = 15” ✔️ 4. 输入:“0123 5” → A无效 → 输出“? + 5 = ?” ✔️ 5. 输入:“0 0” → 两者无效 → 输出“? + ? = ?” ✔️ 6. 输入:“1000 1000” → 有效 → 输出“1000 + 1000 = 2000” ✔️ 7. 输入:“1001 2” → A无效 → 输出“? + 2 = ?” ✔️ 8. 输入:“123” → B为空 → B无效 → 输出“123 + ? = ?” ✔️ 9. 输入:“abc def” → 两者无效 → 输出“? + ? = ?” ✔️ 10. 输入:“123 45a” → B无效 → 输出“123 + ? = ?” ✔️ 11. 输入:“ 12 34 ” → 处理成“12 34”,分割正确 → 输出“12 + 34 = 46” ✔️ 这样,代码应该能正确处理这些情况。 现在,用户提供的引用中的代码是否正确? 例如,引用[1]中的代码: A,B = input().split() 这样在输入有多个空格时会分割错误,比如输入“123 456”会被分割成A='123', B='456',导致B有效,但正确的分割应该B是“ 456”,无效。因此,该代码无法正确处理这种情况,导致错误。 而引用[3]中的代码遍历字符直到找到第一个空格,是正确的分割方式。但他们的代码没有先strip()输入,可能导致A或B包含前后空格,例如输入“ 123 456”分割后A=' 123',无效。因此,正确的做法是先strip()。 因此,正确的代码应该包含strip()步骤,然后正确分割。 综上,正确的Python代码如下:</think>### PTA L1-025 正整数A+B 解法 #### 关键思路分析 1. **输入处理**:需要准确分割第一个空格前后的内容作为A和B,使用`.find(' ')`定位分隔符[^4] 2. **有效性验证**: - 必须是纯数字字符串 - 数值范围1-1000 - 不允许前导零(除非数字本身就是0,但0不在范围内) 3. **输出逻辑**:根据A、B的有效性组合输出四种情况 #### 完整代码实现 ```python s = input().strip() space_pos = s.find(' ') A = s[:space_pos] if space_pos != -1 else s B = s[space_pos+1:] if space_pos != -1 else '' def is_valid(num_str): if not num_str: return False if not num_str.isdigit(): return False if len(num_str) > 1 and num_str[0] == '0': return False return 1 <= int(num_str) <= 1000 valid_A, valid_B = is_valid(A), is_valid(B) if valid_A and valid_B: print(f"{A} + {B} = {int(A)+int(B)}") elif valid_A and not valid_B: print(f"{A} + ? = ?") elif not valid_A and valid_B: print(f"? + {B} = ?") else: print("? + ? = ?") ``` #### 代码说明 1. **输入处理**:通过`strip()`去除前后空格,`find(' ')`定位首个空格实现准确分割 2. **有效性检查**:`is_valid()`函数包含四层判断(空值、非数字、前导零、数值范围) 3. **输出分支**:通过布尔值组合判断输出格式,确保所有测试点覆盖
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值