ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

OpenJudge NOI 1.8 23:二维数组回形遍历

2022-03-20 18:00:06  阅读:92  来源: 互联网

标签:sy NOI 23 int 1.8 sj 105 col row


【题目链接】

OpenJudge NOI 1.8 23:二维数组回形遍历

【题目考点】

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;
}

标签:sy,NOI,23,int,1.8,sj,105,col,row
来源: https://blog.csdn.net/lq1990717/article/details/123617595

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有