2018级计科1、计科2、网工、信安班第15周竞赛题题解

前言#

本文中的题目做法仅供参考,不一定是最简单或是最正确的方法。
每题附的程序源码均在当时通过了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;
}

2018级计科1、计科2、网工、信安班第15周竞赛题题解

https://blog.tootal.xyz/posts/2018cs-w15c/

作者

黄智权

本文发布于

2018-12-10

本文更新于

2018-12-10

许可协议

评论