蓝桥杯 试题 基础练习 回形取数 (c++)

本文详细介绍了如何解决回形取数问题,提供了一种直接暴力模拟的算法,通过不断改变方向并检查周围点的有效性来遍历矩阵。代码中包含详细的注释,解释了每个部分的功能,帮助理解算法的运行过程。

题目描述

资源限制
时间限制:1.0s 内存限制:512.0MB

问题描述
  回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转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

算法

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 210;

int m, n;
int g[N][N];    //  点的值
bool st[N][N];  //  是否被遍历过

bool is_valid(int x, int y) { // 判断当前的点是否有效和是否被遍历过
    if (x < 1 || x > m || y < 1 || y > n) return false;
    if (st[x][y] == true) return false;
    return true;
}


int main() {
    cin >> m >> n;
    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= n; j++) {
            scanf("%d", &g[i][j]);
        }

    bool flag = true;
    int nx = 1, ny = 1;
    int dx[4] = {1, 0, -1, 0};
    int dy[4] = {0, 1, 0, -1};
    int direction = 0; // 0为下 1为右 2为上 3为左
    int cnt = 0;

    // 初始化
    printf("%d ", g[1][1]);
    st[1][1] = true;

    while(flag) {
        while(is_valid(nx + dx[direction], ny + dy[direction])) {  // 判断是否下一个点满足条件, 如果满足则将当前的点移动为下一个点, 并输出该点的值
            cnt = 0;
            nx += dx[direction]; // 移动当前的点,移动的方向为direction代表的方向
            ny += dy[direction];
            st[nx][ny] = true;
            printf("%d ", g[nx][ny]);
        }
        cnt ++; // 改变方向的次数自增, 若大于4,则说明周围的点都已经被遍历过了
        direction = (direction + 1) % 4;
        if (cnt == 4) flag = false; // 跳出循环
    }
    return 0;
}

思路

直接暴力模拟就可以了, 具体看代码的注释

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值