2018级C++-第4章课后作业(计科1班、创新班、辅修班)

狠狠吐槽OJ的输入输出,简直有毒。
输出判断设置成逐字节比较(一般是忽略末尾多余的回车与空格)
读入还不给数据组数和数据个数,还改数据!!
目前A题只用stream流输入输出过了。如有其他读入方法,望留言指出。

A#

Problem A: 求平均成绩和方差

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <cstdio>
#include <iostream>
#include <cmath>
#include <string>
#include <sstream>
using namespace std;
int main(){
string s;
while(getline(cin,s)){
istringstream in(s);
int n=0,a[105],sum=0;
while(in>>a[n++]){
sum+=a[n-1];
}
n--;
double avg=1.0*sum/n,dev=0;
for(int i=0;i<n;i++){
dev+=(a[i]-avg)*(a[i]-avg);
}
dev=sqrt(dev/n);
cout<<avg<<' '<<dev<<'\n';
}
}

B#

Problem B: 按要求输出数组

选择排序#

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
#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct point{
int val,pos;
};
int main(){
//freopen("input.txt","r",stdin);
//freopen("answer.txt","w",stdout);
string s;
while(getline(cin,s)){
stringstream in(s);
int n=0;
point a[105];
while(in>>a[n++].val)
a[n-1].pos=n-1;
n--;
for(int i=0;i<n-1;i++)
for(int j=i;j<n;j++)
if(a[i].val<=a[j].val)swap(a[i],a[j]);
for(int i=0;i<n;i++)
printf("%d_%d%c",a[i].val,a[i].pos,(i==n-1)?'\n':' ');
}
return 0;
}

sort#

这题用sort+cmp(强行不稳定排序)也可以过。
但这种做法及其危险,通过对拍发现
sort如果cmp函数在两个元素相等情况下返回真,有可能会陷入死循环。
这与sort内部实现机制有关,具体就不深究了。

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 <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;
struct point{
int val,pos;
};
bool cmp(point x,point y){
return x.val>=y.val;
}
int main(){
//freopen("input.txt","r",stdin);
string s;
while(getline(cin,s)){
stringstream in(s);
int n=0;
point a[105];
while(in>>a[n++].val){
a[n-1].pos=n-1;
//printf("a[%d].val=%d,a[%d].pos=%d\n",n-1,a[n-1].val,n-1,a[n-1].pos);
}
n--;
/*
for(int i=0;i<n-1;i++){
for(int j=i;j<n;j++){
if(a[i].val<=a[j].val)swap(a[i],a[j]);
}
}*/
sort(a,a+n,cmp);
/*for(int i=0;i<n;i++)
printf("a[%d].val=%d,a[%d].pos=%d\n",i,a[i].val,i,a[i].pos);*/
for(int i=0;i<n;i++){
printf("%d_%d%c",a[i].val,a[i].pos,(i==n-1)?'\n':' ');
}
}
return 0;
}

其中cmp函数可改写成这样。

1
2
3
4
bool cmp(point x,point y){
if(x.val!=y.val)return x.val>y.val;
else return x.pos>y.pos;
}

qsort#

好久没用了,虽然用的少,但是有时候还是比sort快。
虽然qsort本身是不稳定的,但是这题。。。

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
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;
struct point{
int val,pos;
};
int cmp(const void *x,const void *y){
if((((point*)y)->val)!=(((point*)x)->val))
return (((point*)y)->val)-(((point*)x)->val);
else return (((point*)y)->pos)-(((point*)x)->pos);
}
int main(){
//freopen("input.txt","r",stdin);
string s;
while(getline(cin,s)){
stringstream in(s);
int n=0;
point a[105];
while(in>>a[n++].val){
a[n-1].pos=n-1;
//printf("a[%d].val=%d,a[%d].pos=%d\n",n-1,a[n-1].val,n-1,a[n-1].pos);
}
n--;
/*
for(int i=0;i<n-1;i++){
for(int j=i;j<n;j++){
if(a[i].val<=a[j].val)swap(a[i],a[j]);
}
}*/
qsort(a,n,sizeof(point),cmp);
/*for(int i=0;i<n;i++)
printf("a[%d].val=%d,a[%d].pos=%d\n",i,a[i].val,i,a[i].pos);*/
for(int i=0;i<n;i++){
printf("%d_%d%c",a[i].val,a[i].pos,(i==n-1)?'\n':' ');
}
}
return 0;
}

C#

Problem C: 判断回文数
首尾逐字符比较即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <cstring>
using namespace std;
int main(){
char s[105];
while(cin>>s){
int len=strlen(s);
int f=1;
for(int i=0;i<((len+1)>>1);i++){
if(s[i]!=s[len-i-1]){
f=0;
break;
}
}
cout<<(f?"YES":"NO")<<endl;
}
return 0;
}

D#

Problem D: 按要求合并数组
依次从两个数组中选取较小的元素即可。
归并排序思想。

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
#include <iostream>
using namespace std;
int main(){
//freopen("input.txt","r",stdin);
int n,m;
while(cin>>n>>m){
int a[105],b[105],c[210];
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=0;i<m;i++){
cin>>b[i];
}
int la=0,lb=0,lc=0;
a[n]=b[m]=1e9;
while(la<n||lb<m){
if(a[la]<=b[lb])c[lc++]=a[la++];
else c[lc++]=b[lb++];
}
for(int i=0;i<lc;i++){
cout<<c[i]<<((i==lc-1)?'\n':' ');
}
}
return 0;
}

E#

Problem E: 用英文表示星期数

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;
char *weekday[7]={"sunday","monday","tuesday","wednesday","thursday","friday","saturday"};
int main(){
int n;
while(cin>>n){
cout<<weekday[n]<<endl;
}
return 0;
}

F#

Problem F: 矩阵操作
create|del|main_diagonal
OJ上的图炸了,这里放一张图。

使用矩阵操作#

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>
using namespace std;
int M[105][105];
void create(int a[][105],int n){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(j>=i)a[i][j]=1;
else a[i][j]=i-j+1;
}
}
}
void del(int a[][105],int n){
for(int i=1;i<=n;i++){
a[1][i]=a[2][i]=a[i][1]=a[i][2]=0;
}
}
int main_diagonal(int a[][105],int n){
int sum=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i>j)sum+=a[i][j];
}
}
return sum;
}
int main(){
int n;
while(cin>>n){
create(M,n);
del(M,n);
cout<<main_diagonal(M,n)<<endl;
}
return 0;
}

不使用矩阵操作#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//keywords:create del main_diagonal
//Keep It Simple and Stupid
#include <iostream>
using namespace std;
int main(){
int n;
while(cin>>n){
int sum=0;
for(int i=2;i<=n-2;i++){
sum+=(n-i)*(i-1);
}
cout<<sum<<endl;
}
return 0;
}

G#

Problem G: 对数组重新排序

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
46
#include <iostream>
#include<string>
using namespace std;
void insert(int a[], int n){
int i=1, p = 1;
while (i <= n - 3){
if ((a[i] > a[n])&&p){
cout << a[n]<<' ';
p = 0;
i--;
}else{
if ((a[i] < a[n]) || p == 0)
cout << a[i] << ' ';
else
if ((a[i] == a[n])&&p){
cout << a[i] << ' ' << a[i] << ' ';
p = 0;
}
}
i++;
}
if (p){
if (a[n] < a[n - 2]) cout << a[n] << ' ' << a[n - 2];
else
cout << a[n - 2] << ' '<<a[n];
}
else cout << a[n - 2];
cout << endl;
}
int main(){
string s;
int i, j, n;
int a[100] = {0};
while (getline(cin, s)){
n = 1;
j = 1;
for (i = 0; i < s.size(); i++){
if (s[i] == ' ') { a[n] = a[n] * j; n += 1; j = 1; continue; }
if (s[i] == '-') { j = -1; continue; }
a[n] = a[n] * 10 + (int)(s[i]) - 48;
}
a[n] *= j;
insert(a, n);
for (i = 1; i <= n; i++) a[i] = 0;
}
}

H#

Problem H: 找出最小关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int main(){
//freopen("input.txt","r",stdin);
char s[105][105];
int n=0;
while(cin>>s[n++]){
char c=cin.get();
if(c=='\n'||c==-1){
int mini=0;
for(int i=1;i<n;i++){
if(strcmp(s[mini],s[i])>0)mini=i;
}
cout<<s[mini]<<endl;
n=0;
}
}
return 0;
}

GH后来修改了keyword,stringstream被禁了。重写了一下。。。

2018级C++-第4章课后作业(计科1班、创新班、辅修班)

https://blog.tootal.xyz/posts/2018cpp-hw4/

作者

黄智权

本文发布于

2018-11-18

本文更新于

2018-11-18

许可协议

评论