两个题目均取自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;
}

运行结果如:

欢迎留言讨论,提出更简便方法。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐