前言
本文中的题目做法仅供参考,不一定是最简单或是最正确的方法。
每题附的程序源码均在当时通过了OJ测试,但随着时间的推移也有可能失效。
作者水平有限,如有疏漏,在所难免,望留言指出。
A
Problem A: 忽略大小写比较字符串大小
逐个字符比较,遇到不同的就返回。当两个字符均为0时结束。
忽略大小写,这里采用了将所有的大写字母转换成小写字母来处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | #include <iostream> using namespace std; int MyStrCmp(char *pStr1,char *pStr2){ 	for(int i=0;;i++){ 		if(pStr1[i]>='A'&&pStr1[i]<='Z')pStr1[i]+='a'-'A'; 		if(pStr2[i]>='A'&&pStr2[i]<='Z')pStr2[i]+='a'-'A'; 		if(pStr1[i]>pStr2[i])return 1; 		else if(pStr1[i]<pStr2[i])return -1; 		if(pStr1[i]==0&&pStr2[i]==0)return 0; 	} } int main(){ 	char s1[25],s2[25]; 	while(cin>>s1>>s2){ 		int ans=MyStrCmp(s1,s2); 		if(ans==0)printf("=\n"); 		else if(ans==1)printf(">\n"); 		else if(ans==-1)printf("<\n"); 	} 	return 0; }
 
   | 
 
B
Problem B: 超大整数加法
当数字远远超过已有的数据类型时,只有用字符串来读入处理了。
先读入,再把字符串中的字符转换成数字存到数组里。(注意存到数组里的顺序是相反的,方便进位)
然后按位相加,处理进位即可。
这里的top用来处理数字前面不需要的0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
   | #include <iostream> #include <cstring> using namespace std; int main(){ 	char s1[305],s2[305]; 	int a1[305],a2[305]; 	while(cin>>s1>>s2){ 		memset(a1,0,sizeof(a1)); 		memset(a2,0,sizeof(a2)); 		int len1=strlen(s1),len2=strlen(s2); 		for(int i=0;i<len1;i++){ 			a1[len1-i-1]=s1[i]-'0'; 		} 		for(int i=0;i<len2;i++){ 			a2[len2-i-1]=s2[i]-'0'; 		} 		for(int i=0;i<len2;i++){ 			a1[i]+=a2[i]; 			if(a1[i]>=10){ 				a1[i+1]+=a1[i]/10; 				a1[i]%=10; 			} 		} 		int top=300; 		while(a1[top]==0)top--; 		for(int i=top;i>=0;i--){ 			cout<<a1[i]; 		} 		cout<<endl; 	} 	return 0; }
 
   | 
 
C
Problem C: 消费情况调查
按照题意模拟,这里交换元素用了algorithm库文件里的swap函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
   | #include <iostream> #include <string> #include <algorithm> using namespace std; struct stu{ 	string name; 	int ord,pay,back,actpay; 	char sex; }; int main(){ 	int n; 	while(cin>>n){ 		stu s[105]; 		int Msum=0,Wsum=0; 		for(int i=1;i<=n;i++){ 			cin>>s[i].ord>>s[i].name>>s[i].sex>>s[i].pay>>s[i].back; 			s[i].actpay=s[i].pay-s[i].back; 			if(s[i].sex=='M')Msum+=s[i].actpay; 			else if(s[i].sex=='W')Wsum+=s[i].actpay; 		} 		for(int i=1;i<n;i++){ 			for(int j=i+1;j<=n;j++){ 				if(s[i].actpay<s[j].actpay)swap(s[i],s[j]); 			} 		} 		cout<<'M'<<Msum<<" W"<<Wsum<<endl; 		for(int i=1;i<=n;i++){ 			if(s[i].back>=(s[i].pay/2.0))cout<<s[i].ord; 			cout<<s[i].name<<' '; 		} 		cout<<endl; 	} 	return 0; }
 
   | 
 
D
Problem D: Emirp
rev函数用于反转数字,check函数判断是否为质数。
这里采用了先预处理出10000以内的符合条件的数字,记录在is数组里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
   | #include <iostream> #include <cmath> using namespace std; int rev(int x){ 	int ans=0; 	while(x){ 		ans=ans*10+x%10; 		x/=10; 	} 	return ans; } int check(int x){ 	int temp=int(sqrt(x)+1); 	for(int i=2;i<temp;i++){ 		if(x%i==0)return 0; 	} 	return 1; } int is[10005]; int main(){ 	for(int i=2;i<=10000;i++){ 		if(check(i)&&check(rev(i))){ 			is[i]=1; 		} 	} 	int n; 	while(cin>>n){ 		int count=0; 		for(int i=2;;i++){ 			if(is[i]){ 				cout<<i; 				count++; 				if(count%10==0&&count!=n)cout<<endl; 				else if(count==n){ 					cout<<endl; 					break; 				}else cout<<' '; 			} 		} 	} 	return 0; }
 
   | 
 
E
Problem E: 数组位置交换及序号名次统计
由于只能用一个数组交换元素,这里利用了下标n以后的空间暂存。
(其实也可以不交换)
显然一个数的排名=大于这个数的个数+1
暴力枚举统计即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
   | #include <iostream> using namespace std; void swap(int a[],int m,int n){ 	for(int i=1;i<=m;i++){ 		a[m+n+i]=a[i]; 	} 	for(int i=1;i<=n;i++){ 		a[i]=a[m+i]; 	} 	for(int i=1;i<=m;i++){ 		a[n+i]=a[n+m+i]; 	} } int sortNo(int a[],int m,int n){ 	int x=a[m]; 	int t=1; 	for(int i=1;i<=n;i++){ 		if(a[i]>x)t++; 	} 	return t; } int main(){ 	int n,m; 	while(cin>>n>>m){ 		int s[105]; 		for(int i=1;i<=n;i++){ 			cin>>s[i]; 		} 		cout<<sortNo(s,m,n)<<endl; 		swap(s,m,n-m); 		for(int i=1;i<=n;i++){ 			cout<<s[i]; 			if(i==n)cout<<endl; 			else cout<<' '; 		} 	} 	return 0; }
 
   | 
 
F
Problem F: 子串查找与替换
可以先把str字符串存到strtemp里。用p指向str字符串。p初始化为0。(可以理解为把str字符串清空)
再用i指向strtemp里的字符,逐个处理,对每个字符开始判断是否与find_str相同。
若相同则把replace_str字符串添加在str后面(利用p确定位置),并且i向后跳一段距离。
若不相同则直接把i指向的字符加在str后即可,最后在str末尾添加0截断。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
   | #include <iostream> #include <cstring> using namespace std; int find_replace_str(char str[],const char find_str[],const char replace_str[]){ 	int count=0; 	char strtemp[105]; 	strcpy(strtemp,str); 	int p=0; 	int lens=strlen(str),lenf=strlen(find_str),lenr=strlen(replace_str); 	for(int i=0;i<lens;i++){ 		int f=1; 		if(i<=lens-lenf){ 			for(int j=0;j<lenf;j++){ 				if(strtemp[i+j]!=find_str[j]){ 					f=0; 					break; 				} 			} 		}else f=0; 		if(f){ 			for(int j=0;j<lenr;j++){ 				str[p++]=replace_str[j]; 			} 			i+=lenf-1; 			count++; 		}else{ 			str[p++]=strtemp[i]; 		} 	} 	str[p]=0; 	return count; } int main(){ 	char str[100],find_str[20],replace_str[20]; 	memset(str,0,sizeof(str)); 	int replace_cnt=0; 	while(cin>>str>>find_str>>replace_str){ 		replace_cnt=find_replace_str(str,find_str,replace_str); 		cout<<replace_cnt<<endl; 		cout<<str<<endl; 		memset(str,0,sizeof(str)); 	} 	return 0; }
 
   |