原题摘录-分子量(Molar Mass,ACM/ICPC seoul 2007,UVa1586)
给出一种物质的分子式(不带括号),求分子量.本题中的分子式只包括4种原子,分别为C,H,N,O,原子量为12.01,1.008,14.01,16.00.例如C6H5OH的分子量为6*12.01+5*1.008+1*16.00+1.008=94.108
详解
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <iostream>
#define maxn 256
using namespace std;
int main(int argc, char** argv)
{
int sz;//字符数组中元素的个数
int cnt;//1,实时记录原子个数.2,在记录原子个数后,同时表征三个状态变量 0,1,-1
char buf[maxn];//输入由原子和数字组成的字符数组
char c;//记录数组中的每个元素,即每个原子和数字 ,均可以通过c转化
char s;//s=c,记录原子所对应的英文大写字母,为取W[]的内容(也即原子对应的质量)做准备
//int a; //a=c-'0,记录原子所对应的数字字符,为取原子对应的数量做准备
double W[maxn];//记录每个原子所对应的质量
W['C']=12.01,W['H']=1.008,W['O']=16.0,W['N']=14.01;//初始化赋值
double ans=0;//记录实时的分子量 ,也即要求的答案
cnt=-1;//初始化为-1,表示遇到了新原子 ,因为我们知道字符串第一个字符肯定是原子而不是数字
scanf("%s",buf);//输入字符串
sz=strlen(buf);
for(int i=0;i<sz;i++){
char c=buf[i];
if(isupper(c)){//原子大写字母处理
if(i) {
if(cnt==-1) cnt=1;//标记一:原子后面不带数目,则原子个数化为1
ans+=W[s]*cnt;//计算的是上一次原子的质量
}
s=c;//初始化本次原子
cnt=-1;//一分为二,下一个字符要么是大写原子字母,要么是数字.为原子处理标记一和原子个数数字处理标记二做准备
}
else{ //原子个数数字处理
if(cnt==-1) cnt=0;//标记二:(cnt=-1,说明是新数,那么无旧数,则令旧数为0)
cnt=10*cnt+(c-'0');//旧数+新数
} //一下新旧数的概念是针对多位数建立的;如12,那么对2来说,1就是旧数.
}
if(cnt==-1) cnt=1;//加上最后一个
ans+=W[s]*cnt;
printf("%.3lf\n",ans);//按要求输出结果
return 0;
}
AC代码
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <iostream>
#define maxn 256
using namespace std;
int main(int argc, char** argv)
{
int sz;
int cnt;
char buf[maxn];
char c;
char s;
double W[maxn];
W['C']=12.01,W['H']=1.008,W['O']=16.0,W['N']=14.01;
double ans=0;
cnt=-1;
scanf("%s",buf);
sz=strlen(buf);
for(int i=0;i<sz;i++){
char c=buf[i];
if(isupper(c)){
if(i) {
if(cnt==-1) cnt=1;
ans+=W[s]*cnt;
}
s=c;
cnt=-1;
}
else{
if(cnt==-1) cnt=0;)
cnt=10*cnt+(c-'0');
}
}
if(cnt==-1) cnt=1;
ans+=W[s]*cnt;
printf("%.3lf\n",ans);
return 0;
}