蓝桥杯-回形取数

题目

问题描述

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

代码 1 (暴力解法)

#include <stdio.h>
#define MAXSIZE 220

int main()
{
    int m, n;
    int i, j;
    int num[MAXSIZE][MAXSIZE];
    scanf("%d%d", &m, &n);
    int count = m * n;
    int state = 0;
    for(i=0; i<MAXSIZE; i++){
        for(j=0; j<MAXSIZE; j++){
            num[i][j] = -1;
        }
    }
    for(i=1; i<=m; i++){
        for(j=1; j<=n; j++){
            scanf("%d", &num[i][j]);
        }
    }
    i = 1;
    j = 1;
    while(count > 0){
        if(count == 1){
            printf("%d", num[i][j]);
        }
        else{
            printf("%d ", num[i][j]);
        }
        num[i][j] = -1;
        switch (state) {
            case 0:
                if(num[i+1][j] != -1){
                    i++;
                }
                else{
                    j++;
                    state = 1;
                }
                break;
            case 1:
                if(num[i][j+1] != -1){
                    j++;
                }
                else{
                    i--;
                    state = 2;
                }
                break;
            case 2:
                if(num[i-1][j] != -1){
                    i--;
                }
                else{
                    j--;
                    state = 3;
                }
                break;
            case 3:
                if(num[i][j-1] != -1){
                    j--;
                }
                else{
                    i++;
                    state = 0;
                }
                break;
        }
        count--;
    }
    return 0;
}

代码 2(非暴力解法,自动判断每次需要输出多少个就转弯)

#include <stdio.h>
#include <stdlib.h>

void output(int num, int *count);

int main()
{
    int m, m_input, n;
    int i, j;//计数标识
    int p = 0, q = 0;//初始化指针,归零
    scanf("%d%d", &m_input, &n);
    //创建动态二维数组
    int **num = (int**)malloc(sizeof(int*) * m_input);
    for(i=0; i<m_input; i++){
        num[i] = (int*)malloc(sizeof(int) * n);
    }
    
    m = m_input;
    int count = m * n;
    int state = 0, flag = 0;//state是运行状态,flag是判断m,n中最小值是否为奇数的标识符
    for(i=0; i<m; i++){
        for(j=0; j<n; j++){
            scanf("%d", &num[i][j]);
        }
    }
    //防止初始m或n为1的情况
    if(m > 1){
        m--;
    }
    else{
        flag = 1;
    }
    if(n > 1){
        n--;
    }
    
    while(count > 0){//数没输出完就一直循环
        switch (state) {
            case 0:
                for(i=0; i<m-1; i++){
                    output(num[p][q], &count);
                    p++;
                }
                output(num[p][q], &count);
                if(flag){//m,n中最小值为奇数时,要注意不能再让指针下移了,要右移
                    q++;
                }
                else{
                    p++;
                }
                state = 1;
                break;
            case 1:
                for(i=0; i<n; i++){
                    output(num[p][q], &count);
                    q++;
                }
                state = 2;
                break;
            case 2:
                for(i=0; i<m; i++){
                    output(num[p][q], &count);
                    p--;
                }
                state = 3;
                break;
            case 3:
                for(i=0; i<n-1; i++){
                    output(num[p][q], &count);
                    q--;
                }
                output(num[p][q], &count);//因为是回形输出,3状态结束后指针应向下移
                p++;
                
                m = m - 2;
                n = n - 2;
                if(m == 0){//根据规律,m或n中任何一个减为0,意味着m,n中的最小值为奇数,就应该加1
                    flag = 1;
                    m++;
                }
                if(n == 0){
                    n++;
                }
                state = 0;
                break;
        }
    }
    
    //释放动态数组
    for(i=0; i<m_input; i++){
        free(num[i]);
    }
    free(num);
    return 0;
}

void output(int num, int *count){
    if(*count <= 1){
        printf("%d", num);
    }
    else{
        printf("%d ", num);
    }
    (*count)--;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星耀浮沉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值