2021-2022-2-第8次单元练习后记//Pintia
一个简单的说明
主要以记录题目,分享源码为主
顺带记录做题心路历程
太久没有做题了,手生了,难免犯一些低级错误
最后,顺便对我的后续练习起到一个规划的作用
我真的好想吐槽这套题目的东拼西凑啊,题号都是错的
7-1 解析二维数组 分数 20
题面
读入一个字符串,该字符串表示一个整型二维数组d,数组中的元素通过解析字符串参数获得。例如,字符串参数:“1,2;3,4,5;6,7,8”,对应的数组为:
d[0,0] = 1 d[0,1] = 2
d[1,0] = 3 d[1,1] = 4 d[1,2] = 5
d[2,0] = 6 d[2,1] = 7 d[2,2] = 8
打印这个数组各元素的内容
输入格式:
字符串
输出格式:
二维数组各元素
输入样例:
在这里给出一组输入。例如:
1,2;3,4,5;6,7,8
输出样例:
在这里给出相应的输出。例如:
d[0,0] = 1 d[0,1] = 2
d[1,0] = 3 d[1,1] = 4 d[1,2] = 5
d[2,0] = 6 d[2,1] = 7 d[2,2] = 8
C++源码
#include<cstdio>
#include<string>
#include<iostream>
#include<cstring>
using namespace std;
#define MAXN 10
string a;
int f,s;
int d[MAXN][MAXN],cnt[MAXN],cnts;
char k;
int main(){
cin>>a;
cnts=0;
for(int i=0;i<a.length();++i){
f=1,s=0;
k=a[i];
if(k==',')++cnt[cnts];
else if(k==';') ++cnts;
else if(k=='-')f=-1,k=a[++i];
else{
while(k>='0'&&k<='9'){s=(s<<3)+(s<<1)+k-'0';k=a[++i];}
--i;
d[cnts][cnt[cnts]]=f*s;
}
}
for(int i=0;i<=cnts;++i){
for(int j=0;j<=cnt[i];++j){
printf("d[%d,%d] = %d",i,j,d[i][j]);
//铸币吧,我佛了,这比出题自己不写明格式要求,然后来一首行末空格检查,一点细节扣扣嗖嗖恶心人是吧
if(j<cnt[i])putchar(' ');
}
putchar('\n');
}
return 0;
}
C源码
#include<cstdio>
#include<string>
#include<iostream>
#include<cstring>
using namespace std;
#define MAXN 10
#define MAXM 5001
char a[MAXM];
int f,s;
int d[MAXN][MAXN],cnt[MAXN],cnts;
char k;
int main(){
scanf("%s",a);
cnts=0;
for(int i=0;i<strlen(a);++i){
看到有人问我这题怎么写,就又写了个c的版本上来,其他地方都是一样的,主要是string.h库的strlen这个函数用于获取字符串长度,和c++的length函数意义是一样的。另外就是定义了一个字符数组用于读入,因为需要考虑预设大小,所以我直接懒得打了。
因为懒得打/不想打c版本的字符数组,所以直接上的c++的字符串。btw,哪个想的,自己定义了行末无空格的格式,居然不说,打算让我用提交次数来试验吗?
7-2 二维数组处理(二)分数 10
题面
从键盘输入6行6列的双精度型二维数组。
(1)按行输出二维数组每个元素的值。
(2)将上三角形每个元素的值加1,下三角形每个元素的值减1,对角线元素不变。按行输出二维数组每个元素的值。
(3)求变化后数组的最大值,按输出示例输出最大值的行列号和最大值。输出格式如下:
The max is a[最大值的行下标][最大值的列下标] = 最大值
(4)用数组每个元素除以最大值,得到新的数组并输出。
输出格式要求:输出的每个数字占5列,输出到小数点后2位,右对齐。
输入格式:
双精度二维数组a(6行6列)
输出格式:
按题目要求输出
输入样例:
1 3 5 6 9 3
8 9 7 5 3 3
1 2 3 5 9 7
3 5 6 2 4 6
3 5 2 1 0 5
8 9 5 4 3 1
输出样例:
1.00 3.00 5.00 6.00 9.00 3.00
8.00 9.00 7.00 5.00 3.00 3.00
1.00 2.00 3.00 5.00 9.00 7.00
3.00 5.00 6.00 2.00 4.00 6.00
3.00 5.00 2.00 1.00 0.00 5.00
8.00 9.00 5.00 4.00 3.00 1.00
1.00 4.00 6.00 7.0010.00 4.00
7.00 9.00 8.00 6.00 4.00 4.00
0.00 1.00 3.00 6.0010.00 8.00
2.00 4.00 5.00 2.00 5.00 7.00
2.00 4.00 1.00 0.00 0.00 6.00
7.00 8.00 4.00 3.00 2.00 1.00
The max is a[0][4] = 10.00
0.10 0.40 0.60 0.70 1.00 0.40
0.70 0.90 0.80 0.60 0.40 0.40
0.00 0.10 0.30 0.60 1.00 0.80
0.20 0.40 0.50 0.20 0.50 0.70
0.20 0.40 0.10 0.00 0.00 0.60
0.70 0.80 0.40 0.30 0.20 0.10
C++源码
#include<cstdio>
#include<cstring>
#include<cmath>
#define MAXN 7
double d[MAXN][MAXN];
double maxs=-19260817;
int ia,ja;
int main(){
for(int i=1;i<=6;++i)
for(int j=1;j<=6;++j)scanf("%lf",&d[i][j]);
for(int i=1;i<=6;++i){
for(int j=1;j<=6;++j)printf("%5.2lf",d[i][j]);
putchar('\n');
}
for(int i=1;i<=6;++i)
for(int j=1;j<=6;++j){
if(i<j)d[i][j]+=1.00;
if(i>j)d[i][j]-=1.00;
}
for(int i=1;i<=6;++i){
for(int j=1;j<=6;++j){
printf("%5.2lf",d[i][j]);
if(d[i][j]>maxs){
maxs=d[i][j];
ia=i,ja=j;
}
}
putchar('\n');
}
printf("The max is a[%d][%d] = %5.2lf\n",ia-1,ja-1,maxs);
for(int i=1;i<=6;++i)
for(int j=1;j<=6;++j)d[i][j]/=maxs;
for(int i=1;i<=6;++i){
for(int j=1;j<=6;++j)printf("%5.2lf",d[i][j]);
putchar('\n');
}
return 0;
}
7-3 求二维数组偶数和 分数 10
题面
编写程序,求一个整数二维数组偶数的和。
输入格式:
在一行内输入数组行数和列数m和n(0<m, n<=10)。
以矩阵形式输入数组数据,数据间以空格分隔。
输出格式:
输出偶数和:even_sum = result。
输入样例:
3 4
1 2 3 4
5 6 7 8
1 2 3 4
输出样例:
在这里给出相应的输出。例如:
even_sum = 26
C++源码
#include<cstdio>
#include<cstring>
#include<cmath>
int n,m,sum,temp;
int main(){
sum=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j){
scanf("%d",&temp);
if(temp&1)continue;
sum+=temp;
}
printf("even_sum = %d",sum);
return 0;
}
笑死,根本不需要建数组,某种模拟罢
7-1 求矩阵各行元素之和 分数 10
题面
本题要求编写程序,求一个给定的m×n矩阵各行元素之和。
输入格式:
输入第一行给出两个正整数m和n(1≤m,n≤6)。随后m行,每行给出n个整数,其间
以空格分隔。
输出格式:
每行输出对应矩阵行元素之和。
输入样例:
3 2
6 3
1 -8
3 12
输出样例:
9
-7
15
C++源码
#include<cstdio>
#include<cstring>
#include<cmath>
int n,m,sum,temp;
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) {
sum=0;
for(int j=1;j<=m;++j){
scanf("%d",&temp);
sum+=temp;
}
printf("%d\n",sum);
}
return 0;
}
7-2 判断上三角矩阵 分数 10
题面
上三角矩阵指主对角线以下的元素都为0的矩阵;主对角线为从矩阵的左上角至右下角的连线。
本题要求编写程序,判断一个给定的方阵是否上三角矩阵。
输入格式:
输入第一行给出一个正整数T,为待测矩阵的个数。接下来给出T个矩阵的信息:每个矩阵信息的第一行给出一个不超过10的正整数n。随后n行,每行给出n个整数,其间以空格分隔。
输出格式:
每个矩阵的判断结果占一行。如果输入的矩阵是上三角矩阵,输出“YES”,否则输出“NO”。
输入样例:
3
3
1 2 3
0 4 5
0 0 6
2
1 0
-8 2
3
1 2 3
1 4 5
0 -1 6
输出样例:
YES
NO
NO
C++源码
#include<cstdio>
#include<cstring>
#include<cmath>
int n,sum,temp,t,nos;
int main() {
scanf("%d",&t);
while(t){
nos=0;
sum=0;
scanf("%d",&n);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j){
scanf("%d",&temp);
if(i>j&&temp!=0)++nos;
}
if(!nos)printf("YES\n");
else printf("NO\n");
--t;
}
return 0;
}
这题WA了俩次,第一次是大聪明用的累加和等于零来判断的,结果发现测试样例就杀害了(谢谢你,出题人),第二次是没看见多组数据(
7-3 杨辉三角 分数 10
题面
杨辉三角是中国数学史上的一个伟大成就,在中国南宋数学家杨辉1261年所著的《详解九章算法》一书中记载。杨辉三角每一行上的数字都是二项式系数,其特点是两侧数字为1,其余每个数字等于其肩上两个数字的和。
编程输入一个正整数N,输出杨辉三角的前N行。用二维数组实现,先把各个数值存储到数组中,再输出。
输入格式:
一个整数N,N<20.
输出格式:
按样例格式输出,一行中整数之间隔一个空格。
输入样例:
6
输出样例:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
输入样例:
10
输出样例:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
C++源码
#include<cstdio>
#include<cstring>
#include<cmath>
#define MAXN 21
int n,dp[MAXN][MAXN];
int main() {
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for(int i=1;i<=n;++i)dp[i][1]=dp[i][i]=1;
for(int i=3;i<=n;++i)
for(int j=2;j<i;++j)
dp[i][j]=dp[i-1][j]+dp[i-1][j-1];
for(int i=1;i<=n;++i){
for(int j=1;j<=i;++j){
printf("%d",dp[i][j]);
if(j!=i)putchar(' ');
}
if(i!=n)putchar('\n');
}
return 0;
}
说实话,杨辉三角算是金典二维dp入门题了。不过我第一次写的状态转移方程居然写错了(暴汗),写的是最长公共子序列(dp[i][j]=dp[i-1][j]+dp[i][j-1];而且还是错的,没有写max)。实际上应该是dp[i][j]=dp[i-1][j]+dp[i-1][j-1];
这题也是金典不说无行末空格,很难不骂
本次练习的反思
寄寄寄!
拖了很久才写,五一放假让我彻底懒了,最后是好几天后才写的。呜呜呜,我的榜一首杀(笑死)
刚刚看了人民日报那个打错的线段树模板处刑视频
才又一次惊觉,我的青春已经逝去了啊,线段树是我的青春!
关于源码中read()函数的说明
read()函数为自行定义的一个快速读入整数的函数,不熟悉快读的朋友可以自行改为scanf()语句。