分子量(Molar Mass)&数数字(Digit)||UVa 1586,1225
分子量(Score)&数数字(Digit)||UVa 1586,1225
·
两个题目均取自UVa,分别为UVa 1586和UVa 1225。
分子量
给出一种物质的分子式(不带括号),求分子量。本题中的分子式只包含4中原子,分别为C, H, O, N,分子量分别为12.01,1.008,16.00,14.01(单位:g/mol)。例如,C6H5OH的分子量为94.108g/mol。
分析
1.输入数据保存为字符串;
2.因为原子的个数在原子之后,所以倒序判定字符类型:若为数字则可按照个、十、百的顺序计算原子个数,遇到字母则乘以对应原子量和原子个数;
3.判断类型的函数包含在cctype头文件中。
下面给出参考代码:
#include<iostream>
#include<cstring>
#include<cctype>
#define MAX 100
using namespace std;
char s[MAX];
const double moc = 12.01;
const double moh = 1.008;
const double moo = 16.00;
const double mon = 14.01;
int main(){
int num, sum = 0, q = 1; double M = 0.0;
scanf("%s", s);
for(int i = strlen(s); i>=0; i--){
if(isdigit(s[i])){
num = s[i]-'0';//由ASCII码取得数字
sum+=num*q;
q = q*10;
}
if(isalpha(s[i])){
switch(s[i]){
case 'C': M+=sum*moc; sum = 0; q = 1; break;
case 'H': M+=sum*moh; sum = 0; q = 1; break;
case 'O': M+=sum*moo; sum = 0; q = 1; break;
case 'N': M+=sum*mon; sum = 0; q = 1; break;
}
}
}
cout<<M<<"\n";
return 0;
}
数数字
把前n个整数顺次写在一起:0123456789101112……数一数0~9各出现多少次(输出10个整数,分别是0,1,…,9出现的次数)。
分析
不用做复杂分析得出什么前n个数字一共有几个0~9数字的数学公式,大量的判定工作都交给计算机完成。
#include<iostream>
#include<cstring>
using namespace std;
int main(){
int n;
cin>>n;
int a[n+1][10];
memset(a, 0, sizeof(a));
for(int i = 1; i<n+1; i++){
for(int j = 1; j<=i; j++){
int k = j;
while(k!=0){
int q = k%10; k/=10;
switch(q){
case 0: a[i][0]++; break;
case 1: a[i][1]++; break;
case 2: a[i][2]++; break;
case 3: a[i][3]++; break;
case 4: a[i][4]++; break;
case 5: a[i][5]++; break;
case 6: a[i][6]++; break;
case 7: a[i][7]++; break;
case 8: a[i][8]++; break;
case 9: a[i][9]++; break;
}
}
}
}
for(int i = 0; i<10; i++){
cout<<a[n][i]<<"\t";
}
return 0;
}
取上限10000,结果如下:
可见运行时间并不算太长。
但若要求多次输入n,并返回结果呢?仍然在每次输入后都进行循环判定并计数吗?答案是否定的。因为这样做难免会大大增加运行时间。但若将前10000个正整数顺次写在一起的结果事先计算出来并保存到数组中,那么每次输入n后只需“查表”即可返回对应结果。下面的改进程序即运用了此思想:
#include<iostream>
#include<cstring>
const int MAX = 10001;
using namespace std;
int main(){
int n;
int a[MAX][10];
memset(a, 0, sizeof(a));
for(int i = 1; i<MAX; i++){
for(int j = 1; j<=i; j++){
int k = j;
while(k!=0){
int q = k%10; k/=10;
switch(q){
case 0: a[i][0]++; break;
case 1: a[i][1]++; break;
case 2: a[i][2]++; break;
case 3: a[i][3]++; break;
case 4: a[i][4]++; break;
case 5: a[i][5]++; break;
case 6: a[i][6]++; break;
case 7: a[i][7]++; break;
case 8: a[i][8]++; break;
case 9: a[i][9]++; break;
}
}
}
}
while(scanf("%d", &n)==1&&n){
for(int i = 0; i<10; i++){
cout<<a[n][i]<<"\t";
}
cout<<"\n";
}
return 0;
}
运行结果如:
欢迎留言讨论,提出更简便方法。
更多推荐
已为社区贡献1条内容
所有评论(0)