蓝桥杯试题集试题总汇(C++)
问题描述
回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度。一开始位于矩阵左上角,方向向下。
输入格式
输入第一行是两个不超过200的正整数m, n,表示矩阵的行和列。接下来m行每行n个整数,表示这个矩阵。
输出格式
输出只有一行,共mn个数,为输入矩阵回形取数得到的结果。数之间用一个空格分隔,行末不要有多余的空格。
样例输入
3 3
1 2 3
4 5 6
7 8 9
样例输出
1 4 7 8 9 6 3 2 5
样例输入
3 2
1 2
3 4
5 6
样例输出
1 3 5 6 4 2
解题思路
从[k,k]
这个位置开始(0<=k<m/2)
进行逆时针遍历,如下图
每圈的开始都是从[k,k]
位置开始,用k记录圈数,循环遍历。
参考代码
#include<iostream>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
int a[n][m];
int i,j;
for(i=0; i<n; i++)//输入数据
{
for(j=0; j<m; j++)
cin>>a[i][j];
}
for(i=0; i<(n+1)/2&&i<(m+1)/2; i++)//这里的i代表圈数,循环的次数i小于行数的一半且小于列数的一半。
{
for(j=i; j<n-i; j++)//这是输出↓
{
if(i==0&&j==0)
{
cout<<a[j][i];//输出第一个元素,之后按cout<<" "<<a[][];就可以避免行末有多余空格。但每次循环一次判断,降低了时间效率
}else
cout<<" "<<a[j][i];
}
for(j=i+1; j<m-i; j++)//输出→
{
cout<<" "<<a[n-i-1][j];
}
if(m-i-1>i) /*当m为奇数时最后一次循环只有左一列的数据。
每进一次循环都读了对称的两列数据,前面i-1次循环读了2i个数据(i从0开始)在这次判断之前又读了一列数据
所以判断有没有对称的右列数据只要判断m-2*i-1是否大于0(等价于m - i - 1 > i) ,下同 */
{
for(j=n-i-2; j>=i; j-- )//输出↑
cout<<" "<<a[j][m-i-1];
}
if(n-i-1>i)
{
for(j=m-i-2; j>i; j--)//输出←
cout<<" "<<a[i][j];
}
}
return 0;
}