【题目链接】
【题目考点】
1. 二维数组
【解题思路】
解法1:移动焦点
设焦点位置,焦点移动同时输出焦点位置的值。焦点从左上角先后以:右下左上右下左上。。。的形式循环移动遍历。如果焦点移出矩阵范围,或焦点下一次要移动到的位置已经有值,那么就改变焦点移动方向,再取下一个位置。
设方向数组的下标d,方向数组dir[d]表示一种方向,d为0,1,2,3分别对应方向右,下,左,上。d=(d+1)%4
即可变为下一个方向。
解法2:递归
递归问题为:从(1,1)位置开始输出row行col列矩阵的外圈元素,然后从(2,2)位置开始输出row-2行col-2列矩阵的外圈元素。
递归出口:矩阵的行或列数量小于1,则结束递归。
【题解代码】
解法1:移动焦点
- 下标从1开始
#include<bits/stdc++.h>
using namespace std;
int main()
{
int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};//方向数组:右下左上
int row, col, a[105][105], d = 0;//d:dir数组的下标
bool vis[105][105] = {};//vis[i][j]:第i,j位置是否已经输出
cin >> row >> col;
for(int i = 1; i <= row; ++i)
for(int j = 1; j <= col; ++j)
cin >> a[i][j];
int fi = 1, fj = 1, si, sj;//(fi,fj):焦点位置 (si,sj)下一个位置
for(int k = 1; k <= row*col; ++k)
{
cout << a[fi][fj] << endl;
vis[fi][fj] = true;
si = fi + dir[d][0], sj = fj + dir[d][1];//设下一个位置(si,sj)
if(si < 1 || si > row || sj < 1 || sj > col || vis[si][sj])//如果下一个位置在矩阵外或已经输出
d = (d+1)%4;//变为下一个方向
fi = fi + dir[d][0], fj = fj + dir[d][1];//移动焦点
}
return 0;
}
- 下标从0开始
#include<bits/stdc++.h>
using namespace std;
int main()
{
int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};//右下左上
int row, col, a[105][105], d = 0;//d:dir数组的下标
bool vis[105][105] = {};//vis[i][j]:第i,j位置是否已经输出
cin >> row >> col;
for(int i = 0; i < row; ++i)
for(int j = 0; j < col; ++j)
cin >> a[i][j];
int fi = 0, fj = 0, si, sj;//(fi,fj):焦点位置 (si,sj)下一个位置
for(int k = 1; k <= row*col; ++k)
{
cout << a[fi][fj] << endl;
vis[fi][fj] = true;
si = fi + dir[d][0], sj = fj + dir[d][1];//设下一个位置(si,sj)
if(si < 0 || si >= row || sj < 0 || sj >= col || vis[si][sj])//如果下一个位置在矩阵外或已经输出
d = (d+1)%4;//变为下一个方向
fi = fi + dir[d][0], fj = fj + dir[d][1];//移动焦点
}
return 0;
}
解法2:递归
- 下标从1开始
#include<bits/stdc++.h>
using namespace std;
int a[105][105];
//从(sx,sy)位置开始输出row行col列矩阵的外圈元素
void solve(int sx, int sy, int row, int col)
{
if(row < 1 || col < 1)
return;
else if(row == 1)//只有一行
{
for(int j = sy; j <= sy+col-1; ++j)
cout << a[sx][j] << endl;
}
else if(col == 1)//只有一列
{
for(int i = sx; i <= sx+row-1; ++i)
cout << a[i][sy] << endl;
}
else//多行多列
{
for(int j = sy; j <= sy+col-2; ++j)
cout << a[sx][j] << endl;
for(int i = sx; i <= sx+row-2; ++i)
cout << a[i][sy+col-1] << endl;
for(int j = sy+col-1; j >= sy+1; --j)
cout << a[sx+row-1][j] << endl;
for(int i = sx+row-1; i >= sx+1; --i)
cout << a[i][sy] << endl;
}
solve(sx+1, sy+1, row-2, col-2);
}
int main()
{
int row, col;
cin >> row >> col;
for(int i = 1; i <= row; ++i)
for(int j = 1; j <= col; ++j)
cin >> a[i][j];
solve(1, 1, row, col);
return 0;
}
- 下标从0开始
#include<bits/stdc++.h>
using namespace std;
int a[105][105];
//从(sx,sy)位置开始输出row行col列矩阵的外圈元素
void solve(int sx, int sy, int row, int col)
{
if(row < 1 || col < 1)
return;
else if(row == 1)//只有一行
{
for(int j = sy; j <= sy+col-1; ++j)
cout << a[sx][j] << endl;
}
else if(col == 1)//只有一列
{
for(int i = sx; i <= sx+row-1; ++i)
cout << a[i][sy] << endl;
}
else//多行多列
{
for(int j = sy; j <= sy+col-2; ++j)
cout << a[sx][j] << endl;
for(int i = sx; i <= sx+row-2; ++i)
cout << a[i][sy+col-1] << endl;
for(int j = sy+col-1; j >= sy+1; --j)
cout << a[sx+row-1][j] << endl;
for(int i = sx+row-1; i >= sx+1; --i)
cout << a[i][sy] << endl;
}
solve(sx+1, sy+1, row-2, col-2);
}
int main()
{
int row, col;
cin >> row >> col;
for(int i = 0; i < row; ++i)
for(int j = 0; j < col; ++j)
cin >> a[i][j];
solve(0, 0, row, col);
return 0;
}