主题:二维数组结构

A 二维矩阵对角线和
Description
计算m×m的方阵的对角线所有元素的和
Input
输入数据有多组,每组第1行为m (2<=m<=10),接下来有m行m列的数据 1<=a(i,j)<=100
Output
对于你刚输入的这个矩阵,输出方阵的对角线所有元素的和(交叉位置元素要多次计算)
Sample Input
3
1 2 3
4 5 6
7 8 9
Sample Output
30

#include <bits/stdc++.h>
using namespace std;
int main()
{int x[12][12],m,sum;while(cin>>m){sum=0;for(int i=1;i<=m;i++){for(int j=1;j<=m;j++)cin>>x[i][j];}for(int i=1;i<=m;i++){for(int j=1;j<=m;j++){if(i==j)sum+=x[i][j];if(i+j==m+1)sum+=x[i][j];}}cout<<sum<<endl;}
}

总结
i=j判断为主对角线元素,i+j=m+1判断为辅对角线元素,分为两个 if 判断均满足则为交叉位置元素

B 矩阵的外围
Description
在军事训练中,战士们站成一个方阵(也可能是一个长方形),每个战士身上都有1个编号,现在军队领导想知道,站在队伍外围战士们的编号之和是多少?
Input
输入数据有多组,每组第一行n和m(1<n,m<=10),代表行数和列数。接下来是n行m列个战士的编号值value[i](0<= value[i] <=100)
Output
在一行内输出外围战士的编号之和
Sample Input
3 3
1 2 3
4 5 6
0 1 0
Sample Output
17

#include <bits/stdc++.h>
using namespace std;
int main()
{int x[12][12],n,m,sum;while(cin>>n>>m){sum=0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++)cin>>x[i][j];}for(int j=1;j<=m;j++)sum+=x[1][j]+x[n][j];for(int i=2;i<=n-1;i++)sum+=x[i][1]+x[i][m];cout<<sum<<endl;}
}

总结
两个for循环分别加和首行、尾行和中间行的首尾

C 五人帮
Description
5人帮的含义就是该数字所对应的上、下、左、右和自己本身的数值之和,请求出矩阵中5人帮的最大值是多少?
Input
输入数据有多组,每组第1行为2个数m和n(1 <m,n<10),代表行数和列数; 接下来输入这m行和n列个数data(i,j) (1< data(i,j)<100)
Output
输出该矩阵5人帮的最大值!
Sample Input
3 4
1 2 3 4
3 4 5 6
2 3 3 9
Sample Output
24

#include <bits/stdc++.h>
using namespace std;
int main()
{int a[15][15],m,n,sum,ma;while(cin>>m>>n){memset(a,0,sizeof(a));for(int i=1;i<=m;i++){for(int j=1;j<=n;j++)cin>>a[i][j];}ma=-1;for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){sum=a[i][j]+a[i][j+1]+a[i][j-1]+a[i+1][j]+a[i-1][j];ma=max(sum,ma);}}cout<<ma<<endl;}return 0;
}

总结
本题陷阱:外围的各元素也可作为五人帮核心元素
解题核心:数组元素全设置为零,从a[1][1]开始赋值,利用最外圈零元素巧妙计算外圈作为五人帮核心时的数值
注:
1.memset(数组名,0,sizeof(数组名)),对于int类型数组只能初始化为0,1或-1(定为1时元素值不是1)
2.max(a,b),返回a,b较大的一个,min(a,b)返回a,b较小的一个

D 回转小矩阵
Description
现在有一个n*m行的矩阵A,逆时针旋转90度形成一个新的矩阵B,将B矩阵输出来
Input
多组样例,第一行两个整数n,m( 1<=n<=100, 1<=m<=100 )然后是n行m列矩阵
Output
输出矩阵B
Sample Input
3 5
1 2 3 4 5
2 4 9 2 1
3 4 5 7 9
Sample Output
5 1 9
4 2 7
3 9 5
2 4 4
1 2 3

#include <bits/stdc++.h>
using namespace std;
int main()
{int x[12][12],n,m;while(cin>>n>>m){for(int i=1;i<=n;i++){for(int j=1;j<=m;j++)cin>>x[i][j];}for(int j=m;j>=1;j--){for(int i=1;i<n;i++)cout<<x[i][j]<<" ";cout<<x[n][j]<<endl;}}
}

总结
从最后一列的第一行开始向下逐个输出,输出时注意格式

E 矩阵相乘
Description
计算2个方阵的乘积
Input
输入数据有多组,每组第1行为m (1 <m<10)表示方阵的大小,接下来为2个m行m列的数据data(i,j) ( 1<data(i,j)<100)
Output
输出这2个方阵的乘积
Sample Input
2
1 2
1 2
3 1
1 3
Sample Output
5 7
5 7

#include <bits/stdc++.h>
using namespace std;
int main()
{int m,a[15][15],b[15][15],ans[15][15];while(cin>>m){memset(ans,0,sizeof(ans));for(int i=1;i<=m;i++){for(int j=1;j<=m;j++)cin>>a[i][j];}for(int i=1;i<=m;i++){for(int j=1;j<=m;j++)cin>>b[i][j];}for(int i=1;i<=m;i++){for(int j=1;j<=m;j++){for(int k=1;k<=m;k++)ans[i][j]+=a[i][k]*b[k][j];}}for(int i=1;i<=m;i++){for(int j=1;j<m;j++)cout<<ans[i][j]<<" ";cout<<ans[i][m]<<endl;}}return 0;
}

总结
计算部分,用两个for循环确定当前所计算的元素的位置,再用一个k来循环 a 的 i 行和 b 的 j 列

F 结构体应用
Description
读入学生的信息:学号(8位整数)、姓名(20个字符)、1门课的成绩(2位小数) 要求用输入、输出函数实现部分子功能
Input
输入数据有1组,每组有n个学生信息。
Output
输出读入的学生信息,每行1个学生信息,各信息之间用2个空格分隔。
Sample Input
5
20140101
Li Ming
85
20140202
Zhao Li
98
20140013
Qiao En
92.5
20140404
Tian Ya
88.5
20140015
Lu Yao
89.4
Sample Output
20140101 Li Ming 85.00
20140202 Zhao Li 98.00
20140013 Qiao En 92.50
20140404 Tian Ya 88.50
20140015 Lu Yao 89.40

#include <bits/stdc++.h>
using namespace std;
struct sa{char name[30],num[10];double score;
}stu[100];
int main()
{int n;cin>>n;for(int i=1;i<=n;i++){cin>>stu[i].num;getchar();gets(stu[i].name);cin>>stu[i].score;}for(int i=1;i<n;i++){cout<<stu[i].num<<"  "<<stu[i].name;printf("  %.2f\n",stu[i].score);}cout<<stu[n].num<<"  "<<stu[n].name;printf("  %.2f",stu[n].score);return 0;
}

总结
名字内有空格,不能用cin来读取,需用gets()整行读取,gets()前要用getchar()把之前的回车吃掉,否则gets()的字符串为空

G 身高问题
Description
输入 n 个学生的信息,每个学生信息包括姓名、身高、学号。编程输出身高最高的学生的信息。
Input
第 1 行一个正整数 n,表示学生个数,n≤100。
以下 n 行,每一行依次输入学生的姓名、身高、学号。
Output
输出最高的学生信息,如存在身高一样的请输出学号小的那个同学。
Sample Input
5
John 172 20160302
David 173 20160306
Jason 168 20160309
Jack 152 20160311
Kitty 147 20160319
Sample Output
David 173 20160306

#include <bits/stdc++.h>
using namespace std;
struct sa{char name[30];int height,num;
}stu[105];
int cmp(sa a,sa b)
{if(a.height!=b.height)return a.height>b.height;elsereturn a.num<b.num;
}
int main()
{int n;cin>>n;for(int i=1;i<=n;i++)cin>>stu[i].name>>stu[i].height>>stu[i].num;sort(stu+1,stu+1+n,cmp);cout<<stu[1].name<<" "<<stu[1].height<<" "<<stu[1].num;return 0;
}

总结
结构体定义时储存学号的num需为int,否则不易于参与排序
注:sort(a+i,a+i+n,cmp)可实现数组a从a[i]到a[i+n]n项的排序,可自定义cmp()函数来制定排序规则,默认为从小到大

H 成绩统计
Description
兴趣小组收集学员成绩信息,每个学员的成绩有两种表示方法,一种用 best、good、poor 三种等级来表示,还有一种就是直接用分数来表示(百分制)。请保存学员成绩信息,并且统计有多少人是用等级来表示成绩的,用分数来表示成绩的人的平均分是多少(取整就行)
Input
第 1 行一个正整数 n(n≤1000)表示学员人数
第 2~n+1 行,每行一个字符和一个字符串,中间用一个空格隔开。第一个字符表示这个学生成绩类型,有 C、N 两种分别代表等级表示和分数表示,第二个字符串表示成绩信息。
Output
一行两个整数,分别表示用等级表示成绩的人数和用分数表示成绩时人的平均分(取整),中间用一个空格隔开
Sample Input
5
C best
C good
N 90
C poor
N 98
Sample Output
3 94

#include <bits/stdc++.h>
using namespace std;
int main()
{int n,score,sum,numc,numn;char mode,grade[10];cin>>n;numc=numn=sum=0;for(int i=1;i<=n;i++){cin>>mode;if(mode=='C'){cin>>grade;numc++;}else{cin>>score;numn++;sum+=score;}}cout<<numc<<" "<<sum/numn;return 0;
}

总结
本题不用储存成绩信息,故不用使用结构体

I 优秀学生
Description
读入学生的信息(最多不超过100个):学号(不超过八位)、姓名(不超过20个字符)、C语言成绩(用整数表示)。统计优秀学生的信息(成绩在90分以上,包括90分)及个数(要求用结构体实现)
Input
输入数据有多组,每组为n个学生的信息;
Output
输出优秀学生的信息及个数。
Sample Input
5
2015001
ZhangSan
90
2015002
LiMing
80
2015003
WangHong
70
2015004
ZhangXiao
95
2015005
WangFang
100
3
2015001
ZhangSan
60
2015002
LiMing
80
2015003
WangHong
85
Sample Output
2015001 ZhangSan 90
2015004 ZhangXiao 95
2015005 WangFang 100
3
0

#include <bits/stdc++.h>
using namespace std;
struct student{char num[10],name[20];int score;
}stu[105];
int main()
{int n,num,best[105];while(cin>>n){num=0;memset(best,0,sizeof(best));for(int i=1;i<=n;i++){cin>>stu[i].num>>stu[i].name>>stu[i].score;if(stu[i].score>=90){num++;best[i]++;}}if(num){for(int i=1;i<=n;i++){if(best[i])cout<<stu[i].num<<" "<<stu[i].name<<" "<<stu[i].score<<endl;}}cout<<num<<endl;}return 0;
}

总结
构建best数组来标记优秀学生的位置,输出时判断num是否为零可减少无优秀学生时的运行时间,多组输入,记得重置num和best数组

J 谁不及格?
Description
把不及格的同学的名单打印。
Input
输入包含多组数据,每组输入一个数n(1<=n<=10),然后接下来输入n个同学的信息,每个同学的信息分3行,第一行姓名name(姓名长度不超过20个字母),第二行学号x,长度为10(例:2015215098),第三行学生的平均加权成绩。
Output
每组数据第一行输出一个数k,表示不及格学生的个数,然后接下来输出3*k行不及格学生信息,第一个k行输出不及格学生姓名(按输入顺序),第二个k行输出学生学号(按输入顺序),第三个k行输出学生成绩(按输入顺序)(保留2位小数)。若是没有同学不及格,那么输出“They are Great!!”。
Sample Input
2
zhu dan
2015213678
79.99
wang meng
2015213902
83.78
1
tiancai
2015234930
59.08
Sample Output
They are Great!!
1
tiancai
2015234930
59.08

#include <bits/stdc++.h>
using namespace std;
struct sa{char name[30],num[20];double score;
}stu[20];
int main()
{int n,num,fall[20];while(cin>>n){num=0;memset(fall,0,sizeof(fall));for(int i=1;i<=n;i++){getchar();gets(stu[i].name);cin>>stu[i].num>>stu[i].score;if(stu[i].score<60){num++;fall[i]++;}}if(num){cout<<num<<endl;for(int i=1;i<=n;i++){if(fall[i])cout<<stu[i].name<<endl;}for(int i=1;i<=n;i++){if(fall[i])cout<<stu[i].num<<endl;}for(int i=1;i<=n;i++){if(fall[i])printf("%.2lf\n",stu[i].score);}}elsecout<<"They are Great!!"<<endl;}return 0;
}

总结
思路与上一题相同,但本题的输入输出数据和格式都有所不同
输入姓名有空格,配套使用getchar()和gets()读取,学号长度超过int型上限,要用字符串储存
输出需用三个for循环分别输出姓名、学号和分数