注意,元素后面可能没有数字,也可能有多个数字。
Code:
#include<cstdio>
#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<cstring>
#include<set>
#include<cmath>
#include<queue>
#include<algorithm>
#define rep(i,j,k) for(int i=j;i<k;++i)
#define mst(a,b) memset((a),(b),sizeof(a))
#include<cstring>
using namespace std;
typedef long long LL;
typedef vector<int,int> pii;
int main()
{
int t;
char s[105];
scanf("%d",&t);
while(t--){
scanf("%s",s);
int n = strlen(s);
int i;
double ans = 0.0;
double q = 0;
int num = 0;
for(i = 0; i < n; ++i){
num = 0;
if(s[i] == 'C') q = 12.01;
if(s[i] == 'H') q = 1.008;
if(s[i] == 'O') q = 16.00;
if(s[i] == 'N') q = 14.01;
if(i+1 == n){//处理最后一个字符不是数字的情况
ans += q;
}
else if(i+1 < n && !isdigit(s[i+1])){//元素后面没有数字
ans += q;
}
else if(i+1 < n && isdigit(s[i+1])){//元素后面可能有多个数字
while(i+1 < n && isdigit(s[i+1])){
num = num*10 + int(s[i+1]-'0');
++i;
}
ans += num*q;
}
}
printf("%.3f\n",ans);
}
return 0;
}
另一种思路,ans[i]记录第i个位置的值,即当第i个为单元素时候直接记录,当其后跟着数字时候,利用sum计算数字个数。
因为最后累加,跟数字的元素被多加了一次,此时需要去掉。
#include<stdio.h>
#include<string.h>
int sum(int pos,int len, char *s){
int ans = 0;
int i;
for(i = pos; i < len; ++i){
if(!(s[i] >= '0' && s[i] <= '9')){
break;
}
}
for(int j = pos; j < i; ++j){
ans = ans*10 + int(s[j]-'0');
}
return ans-1;
}
int main()
{
int t;
char s[105];
double ans[105];
scanf("%d",&t);
while(t--){
scanf("%s",s);
memset(ans,0,sizeof(ans));
int len = strlen(s);
int flag = 0;
for(int i = 0; i < len; ++i){
if(s[i] == 'C') ans[i] = 12.01;
if(s[i] == 'H') ans[i] = 1.008;
if(s[i] == 'O') ans[i] = 16.00;
if(s[i] == 'N') ans[i] = 14.01;
if(!(s[i] >= '0' && s[i] <= '9')){
flag = 0;
}
if((s[i] >= '0' && s[i] <= '9') && !flag){
ans[i] = ans[i-1]*sum(i,len,s);
flag = 1;
}
}
double res = 0.0;
for(int i = 0; i < len; ++i){
res += ans[i];
}
printf("%.3f\n",res);
}
return 0;
}