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