关于这个练习12,整体上来说难度还算可以,按难度上分类可以将题目分为三部分:简单(A~F)、中等(G~J)、偏难(K~O)。A~F题注重基础,只需按照题目简单思考即可写出程序。G~J·题难度中等,需要根据题目所给的矩阵找出规律即可解决:例如矩阵两条对角线上的元素,其中一条对角线上的元素,其横坐标等于纵坐标,而另一条对角线上的元素,其横坐标与纵坐标的和为一定值。K~O题较有难度,需要深入思考解决方案,尤其注意需要打开你的思路,这样才能更好地解决问题。例如O题(矩阵转置),很经典的一道题,想必大家都有所耳闻。但是你是否找到了最简易的方法呢?
O(矩阵转置)
题目描述: KiKi有一个矩阵,他想知道转置后的矩阵(将矩阵的行列互换得到的新矩阵称为转置矩阵),请编程帮他解答。
输入描述: 第一行包含两个整数n和m,表示一个矩阵包含n行m列,用空格分隔。 (1≤n≤10,1≤m≤10) 从2到n+1行,每行输入m个整数(范围-231~231-1),用空格分隔,共输入n*m个数,表示第一个矩阵中的元素。
输出描述: 输出m行n列,为矩阵转置后的结果。每个数后面有一个空格。
通常来说,很容易想到以下的代码实现:
#include<iostream> using namespace std; int main() { int i,j,n,m,a[22][22],b[22][22]; cin>>n>>m; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { cin>>a[i][j]; } } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) b[j][i]=a[i][j]; } for(i=1;i<=m;i++) { for(j=1;j<=n;j++) cout<<b[i][j]<<" "; cout<<endl; } return 0; }但是,能否就只定义一个二维数组来实现呢?答案是肯定的,只需要将矩阵里的元素以横纵坐标互换的形式“改变”元素在矩阵的位置,之后改变一下循环条件输出二维数组即可:
#include<iostream> #include<cstdio> using namespace std; int main() { int n,m,i,j; cin>>n>>m; int a[11][11]; for(i=0;i<n;i++) { for(j=0;j<m;j++) { cin>>a[i][j]; } } for (i=0;i<m;i++) { for (j=0;j<n;j++) { printf("%d ",a[j][i]); } cout<<endl; } return 0; }这样是不是简单许多?只不过是思路很巧妙以至于不容易想到。
再有就是要思路打开,不要拘束于题目。例如K题:
K(求矩阵各列元素的最大值)
题目描述求一个给定的m行n列矩阵各列元素的最大值。
输入描述:输入第一行给出两个正整数m和n(1≤m,n≤10)。随后m行,每行给出n个整数,其间以空格分隔。
输出描述:一行,共n个整数,分别为n列的最大值,用空格分隔。
乍一看,似乎有点束手无策。但仔细想想,可以用一个一维数组(或列指针)存储每列元素的最大值,之后将该数组输出即可:
#include <iostream> using namespace std; int main() { int m,n,i,j; int a[11][11]; int max[11]; cin>>m>>n; for (j=0;j<n;j++) { cin>>a[0][j]; max[j]=a[0][j]; } for (i=1;i<m;i++) { for (j=0;j<n;j++) { cin>>a[i][j]; if (a[i][j]>max[j]) { max[j]=a[i][j]; } } } for (j=0;j<n;j++) { cout<<max[j]; if (j!=n-1) { cout<<" "; } } return 0; }但这样似乎很麻烦,且容易出错。有没有更好的方法呢?当然是有的。如果在输入的矩阵内部比较,并将各列的最大值作为矩阵每列的最后一个元素,最后输出矩阵的最后一行,不就可以了吗?
#include<iostream> using namespace std; int main() { int i,j,n,m,a[22][22]={0},max; cin>>m>>n; for(i=1;i<=m;i++) { for(j=1;j<=n;j++) cin>>a[i][j]; } for(i=1;i<=n;i++) { a[m+1][i]=a[1][i]; for(j=2;j<=m;j++) if(a[m+1][i]<a[j][i])a[m+1][i]=a[j][i]; } for(i=1;i<n;i++) printf("%d ",a[m+1][i]); printf("%d\n",a[m+1][i]); return 0; }这样编写代码的难度就大大降低了。
总结一下,就是先按照题目要求思考,接着试试能否找出规律,最后尝试能否将思路打开,想到更好的简便方法,这样代码的运行时间和占用内存就能进一步降低,达到最优。