OpenJudge[7545]二维数组回形遍历

@二维数组回形遍历

题目大意

  按如图所示的方法遍历输出一个给出的数组。
  
  回形遍历

输入输出

第一行为两个整数n与m表示行数和列数
接下来输入要遍历的数组: n行,每行m个数

输出为n*m行回形遍历得到的数,每个数占一行

算法讨论

  令当前遍历到的位置为(i, j),观察回形遍历图,我们可以发现遍历时共有4种方向,分别是向右(0)、向下(1)、向左(2)、向上(3),而在每种方向遍历时i(0)与j(1)都有特殊的变化方式。我们可以总结得出这样的方向增量:

方向 i(0) j(1)
向右(0) 0 1
向下(1) 1 0
向左(2) 0 -1
向上(3) -1 0


  我们先初始化好方向增量数组D[4][2],然后程序就变得简单了:
    第一步,我们在读取完数组后给它加框。
    接着,我们用f来储存当前的方向,初始为0(向右)。
    然后,进行n*m次如下操作:
      首先将当前点标记为墙(已走过)
      输出当前遍历到位置的数
      如果a[i+D[f][0]][j+D[f][1]]是墙,那么f = (f+1)%4  //循环改变方向
      i与j分别加上当前的方向增量,确定下一个要遍历到的位置

代码实现

#include 
#include 
using namespace std;
int D[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; //初始化方向增量 

int main(){

    int n, m, nums[101][101], f=0;
    scanf("%d %d", &n, &m);
    for (int i = 0; i <= n+1; i++){
        nums[i][0] = 2e9;
        nums[i][m+1] = 2e9;
    }//加框 
    for (int i = 0; i <= m+1; i++){
        nums[0][i] = 2e9;
        nums[n+1][i] = 2e9;
    }//加框 

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            scanf("%d", &nums[i][j]);
    int i=1, j=1; 
    for (int k = 0; k < n*m; k++){
        printf("%d\n", nums[i][j]);
        nums[i][j] = 2e9;//记录已走过 
        if (nums[i+D[f][0]][j+D[f][1]] == 2e9) f = (f+1)%4;//将要撞墙则改变方向 
        i += D[f][0];
        j += D[f][1];
    }   

    return 0;

}

你可能感兴趣的:(题目解析)