ICode9

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

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

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

标签: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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

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

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

ICode9版权所有