P6051 [RC-02] 求和 题解

Content

输入一行字符串\(s\),提取出\(s\)中的所有数字(如果负号前后都有数字的话不算做负号而是间隔符)并输出它们的和。

数据范围:设第\(i\)行字符串中数字个数为\(cnt_i\),每个数字为\(num_{i,j}(j\in[1,cnt_i])\)。则\(|s|\leqslant1000,cnt_i\leqslant200,|num_{i,j}|\leqslant10^7,1\leqslant i\leqslant100\)。

Solution

字符串模拟题。

废话不说,我们来理一下思路:

首先,读入一行字符串。这里建议用\(\texttt{gets}\)读入一个字符数组(\(\texttt{char}\)类型)。
然后从第一个字符的下标开始,在线寻找是否有数字和负号。这时坑点就来了。

坑点1:如果负号前后都有数字,不算做后面数字的负号而是一个没用的间隔符。

判断完之后就开始记录数字了。这里和快读有些类似,设\(x=0,f=1\),其中\(x\)就是记录数字的,\(f\)就是判断正负的,这个大家应该都清楚。如果数字前面是负号(前提是判断完后是非间隔符),那么一开始\(f\)就是\(-1\)。然后往后推数字,并计入\(x\)中。最后总和直接加上\(x\times y\)就可以了。

这时又有坑点出现了:

坑点2:如果没有数字,什么都不要输出。

以下的代码中用的是一个\(\texttt{num}\)数组存储数字,并用\(\texttt{cnt}\)这个变量来记录数字个数。所以,如果是这样的话,那么字符串里没有数字,自然就意味着\(\texttt{cnt}\)这个变量等于0,就不用输出了,否则输出总和。

细节有点多,细细琢磨。

Code

#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;

char a[1007];

int main() {
	while(gets(a)) {
		int num[207] = {0}, sum = 0, n = strlen(a), cur = 0, cnt = 0;
		while(cur < n) {
//			printf("%c ", a[cur]);
			if((a[cur] >= '0' && a[cur] <= '9') || (a[cur] == '-' && (a[cur + 1] >= '0' && a[cur + 1] <= '9') && (a[cur - 1] < '0' || a[cur - 1] > '9'))) {
				int x = 0, f = 1;
				if(a[cur] == '-') {f = -1; cur++;}
				while(a[cur] >= '0' && a[cur] <= '9') {
					x = x * 10 + (a[cur] - '0');
					cur++;
//					printf("%d\n", x);
				}
				num[++cnt] = x * f;
//				printf("%d %d\n\n", num[cnt], cnt); 
			}
			else	cur++;
		}
		if(!cnt)	continue;
		for(int i = 1; i <= cnt; ++i)
			sum += num[i];
		printf("%d\n", sum);
	}
	return 0;
}
上一篇:LaTeX/宏包: caption


下一篇:CF729A Interview with Oleg 题解