- 题目描述:
-
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
- 输入:
-
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行包括两个整数m和n(1<=m,n<=1000):表示矩阵的维数为m行n列。
接下来的m行,每行包括n个整数,表示矩阵的元素,其中每个元素a的取值范围为(1<=a<=10000)。
- 输出:
-
对应每个测试案例,输出一行,
按照从外向里以顺时针的顺序依次打印出每一个数字,每个数字后面都有一个空格。
样例输入:
4 4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
样例输出:
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
【解题思路】这道题目首先给人一种似曾相识的感觉,当完成代码之后发现不对劲,原因就是这次打印的是矩形而不是方阵。所以首先要解决的问题就是当我们在循环的打印每一圈的同时我们怎么保证循环的停止。仔细分析后我们会发现当矩形是m*n时,循环的圈数loop为m、n中较数的一半。且,我们发现若这个较小的数为一个奇数则最后循环打印完成后肯定会剩余一行或者一竖列元素,需要最后单独处理一下。对于每个循环我们维护一个行的最大值hidx和一个列的最大值sidx,便于确定遍历的边界,每次循环从(i,i)元素开始。
AC code:
#include <cstdio> #include <vector> using namespace std; int main() { int m,n; while(scanf("%d%d",&m,&n)!=EOF) { vector<vector<int> > vec(m); for(int i=0;i<m;++i) for(int j=0;j<n;++j) { int tt; scanf("%d",&tt); vec[i].push_back(tt); } int hidx=n-1,sidx=m-1,loop=m<n?m/2:n/2,ned=0; if(m<=n && m%2==1) ned=-1; if(n<=m && n%2==1) ned=1; int i=0; for(;i<loop;++i) { int idx1=i,idx2=i; while(idx2<hidx)printf("%d ",vec[idx1][idx2++]); while(idx1<sidx)printf("%d ",vec[idx1++][idx2]); while(idx2>i)printf("%d ",vec[idx1][idx2--]); while(idx1>i)printf("%d ",vec[idx1--][idx2]); --hidx; --sidx; } if(ned==-1) for(int j=i;j<=hidx;++j) printf("%d ",vec[i][j]); else if(ned==1) for(int j=i;j<=sidx;++j) printf("%d ",vec[j][i]); printf(" "); } return 0; } /************************************************************** Problem: 1391 User: huo_yao Language: C++ Result: Accepted Time:540 ms Memory:1184 kb ****************************************************************/题目链接:http://ac.jobdu.com/problem.php?pid=1391九度-剑指Offer习题全套答案下载:http://download.csdn.net/detail/huoyaotl123/8276299