为了顺时针输出矩阵,我造了一只吃数据的虫子

题目描述:

给定一个 m行、n 列的矩阵,请按照顺时针螺旋的顺序输出矩阵中所有的元素(从[0][0]位置开始,具体请参见下图)。
输出方式示意图

输入格式:

每次程序运行时,首先在第一行输入 22 个整数,分别对应题目描述中的 m 和 n(1≤m,n≤100),之间用一个空格分隔。接下来输入 m 行,每行包含 n 个整数(取值范围:[-10000,10000]),每两个整数之间用一个空格分隔。

输出格式:

输出为一行,包括 m×n 个整数,按照题目要求的顺序依次输出所有矩阵元素,任意两个整数之间用一个空格分隔,最后一个整数后面没有空格。

输入示例:

7 10
18 31 29 6 16 74 60 83 31 86
64 39 9 87 24 31 43 23 23 93
56 78 32 50 75 86 78 78 49 99
6 57 15 90 58 99 19 88 45 62
39 29 35 3 82 87 39 5 95 71
29 78 34 83 19 17 21 94 7 28
66 87 66 58 52 3 55 95 38 76

输出示例:

18 31 29 6 16 74 60 83 31 86 93 99 62 71 28 76 38 95 55 3 52 58 66 87 66 29 39 6 56 64 39 9 87 24 31 43 23 23 49 45 95 7 94 21 17 19 83 34 78 29 57 78 32 50 75 86 78 78 88 5 39 87 82 3 35 15 90 58 99 19

思路分析:

看到这个题目的时候,我产生了两个想法:
一个是在输入的时候直接按照输出的顺序储存数据,优点是输出简单,遍历一维数组即可;缺点是输入复杂;限制条件是输入的时候因为是从stdin获取,好像无法随机读取,文件或许可以实现。
所以我选择了第二种:输入简单,输出麻烦一些。就是输入的时候正常输入,输出的时候按照要求的顺序。

我的解法:

灵感来源:蚕吃桑叶
定义一只虫子worm,
有触须cirrus,负责搜寻数据寻找方向;有头head,负责“吃”(输出数据,并把经过的数据清零);有尾巴tail,辅助辨别身体的朝向(点是没有方向的,所以只有head不行)。
因为题目要求顺时针,这个问题可以简化很多。只需要判断前方和右边(虫子身体的右边)是否有数据即可。
虫子移动的距离用循环控制,定义一个计数变量,每“吃掉”一个数据,计数变量加一,当"吃掉"(m * n)个数据之后停止。
输出数据后清零原因;即防止重复输出数据,也避免了判断边界的麻烦(所以定义的矩阵MAX == 102);
代码实现:

#include <stdio.h>
#include <string.h>
#define MAX 102
typedef struct Worm{
    int *cirrus;
    int *head;
    int *tail;
}Worm;
Worm worm = {0};
void Scan (int matrix[MAX][MAX], int row, int col);
void Eat (void);
int Sniff (void);
void Right (void);
void Down (void);
void Left (void);
void Up (void);
void Move (int key);
void Print (int matrix[MAX][MAX], int row, int col);
int main() {
    int matrix[MAX][MAX];
    int row;
    int col;
    memset (matrix, 0, sizeof(matrix));
    scanf ("%d %d\n", &row, &col);
    Scan (matrix, row, col);
    Print (matrix, row, col);
    return 0;
}
void Scan (int matrix[MAX][MAX], int row, int col) {
    int counter1, counter2;
    for (counter1 = 1; counter1 <= row; counter1++) {
        for (counter2 = 1; counter2 <= col; counter2++) {
            scanf ("%d", &(matrix[counter1][counter2]));
            getchar();
        }
    }
}
void Right (void) {
	worm.tail = worm.head;
    worm.head++;
}
void Down (void) {
	worm.tail = worm.head;
    worm.head += MAX;
}
void Left (void) {
	worm.tail = worm.head;
    worm.head--;
}
void Up (void) {
	worm.tail = worm.head;
    worm.head -= MAX;
}
void Move (int key) {
    if (key == 6) {
        Right();
        return ;
    }
    if (key == 4) {
        Left();
        return;
    }
    if (key == 8) {
        Up();
        return;
    }
    if (key == 2) {
        Down();
        return;
    }
}
void Eat (void) {
    printf("%d", *(worm.head));
    *(worm.head) = 0;
}
int Sniff (void) {
	if (worm.head - worm.tail == 1) {//身体向右
		if (*(worm.cirrus = worm.head + 1) != 0) {//右
        	return 6;
    	} else if (*(worm.cirrus = worm.head + MAX) != 0) {//下
        	return 2;
    	}
	}
	if (worm.head - worm.tail == MAX) {//身体向下
		if (*(worm.cirrus = worm.head + MAX) != 0) {//下
        	return 2;
    	} else if (*(worm.cirrus = worm.head - 1) != 0) {//左
        	return 4;
    	}
	}
	if (worm.head - worm.tail == -1) {//身体向左
		if (*(worm.cirrus = worm.head - 1) != 0) {//左
        	return 4;
    	} else if (*(worm.cirrus = worm.head - MAX) != 0) {//上
        	return 8;
    	}
	}
	if (worm.head - worm.tail == -MAX) {//身体向上
		if (*(worm.cirrus = worm.head - MAX) != 0) {//上
        	return 8;
    	} else if (*(worm.cirrus = worm.head + 1) != 0) {//右
        	return 6;
    	}
	}
}
void Print (int matrix[MAX][MAX], int row, int col) {
    int counter;
    worm.head = &matrix[1][0];
    worm.tail = worm.head - 1;
    for (counter = 1; counter <= row * col; counter++) {
        Move(Sniff());//寻找数据并向数据移动
        Eat();//输出元素后清零
        counter != row * col && putchar(' ');
    }
}
/*

7 10
18 31 29 6 16 74 60 83 31 86
64 39 9 87 24 31 43 23 23 93
56 78 32 50 75 86 78 78 49 99
6 57 15 90 58 99 19 88 45 62
39 29 35 3 82 87 39 5 95 71
29 78 34 83 19 17 21 94 7 28
66 87 66 58 52 3 55 95 38 76

18 31 29 6 16 74 60 83 31 86 93 99 62 71 28 76 38 95 55 3 52 58 66 87 66 29 39 6 56 64 39 9 87 24 31 43 23 23 49 45 95 7 94 21 17 19 83 34 78 29 57 78 32 50 75 86 78 78 88 5 39 87 82 3 35 15 90 58 99 19

*/

时间复杂度:O(n);
空间复杂度:O(1);

题目来源:

题目来源:开课吧

开课吧
https://xue.kaikeba.com/interactive-course/11779
(我是从这里知道的)

类似题目:

Leetcode:
https://leetcode.com/problems/spiral-matrix/description/

一些废话:

菜鸟一只,互相交流,共同成长。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

时空流亡者

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

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

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

打赏作者

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

抵扣说明:

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

余额充值