PAT 1050螺旋矩阵的代码实现及错误分析(C语言)

题目

本题要求将给定的N个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第1个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为m行n列,满足条件:m*n等于N;m>=n;且m-n取所有可能值中的最小值。

输入格式:

输入在第1行中给出一个正整数N,第2行给出N个待填充的正整数。所有数字不超过10^4^,相邻数字以空格分隔。

输出格式:

输出螺旋矩阵。每行n个数字,共m行。相邻数字以1个空格分隔,行末不得有多余空格。

输入样例:

12
37 76 20 98 76 42 53 95 60 81 58 93

输出样例:

98 95 93
42 37 81
53 20 76
58 60 76

实现思路:先计算出矩阵的行与列,然后按照定义,一圈一圈循环赋值,最后输出数组

1.输入;

2.从平方根向前寻找整除项,第一个即可,定义矩阵数组;(注:如果存在整数平方根,则即为结果,m=n,如果不存在,则离平方根最近的整除项的差值最小,另外不能向后寻找,因为sqrt函数返回double类型,转换为int会向下取整,有可能刚好可以整除,如12的平方根大概是3.46,取int为3,而刚好可以整除,最大最小值会相反)

3.圈数即为n/2,分成4部分循环赋值,最后如果n是奇数,处理最后剩下的中间一列;

4.输出。

代码如下:

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

int cmp(const void *a, const void *b)
{
  return *((int *)b)-*((int *)a);
}

int main()
{
  int n=0;
  scanf("%d",&n);
  int iData[n];
  for(int i=0;i<n;i++)
  {
    scanf("%d",&iData[i]);
  }
  qsort(iData,n,sizeof(int),cmp);
  int iM=0,iN=0;
  // int iMin=n;
  // for(int i=1;i<sqrt(n)+1;i++)
  // {
  //   if(n%i==0)
  //   {
  //     if(iMin>=(n/i-i))
  //     {
  //       iMin=n/i-i;
  //       iM=n/i;
  //       iN=i;
  //     }
  //   }
  // }
  for(int i=(int)sqrt(n);i>0;i--)//从平方根反向寻找,效率更高
  {
    if(n%i==0)
    {
      iM=n/i;
      iN=i;
      break;
    }
  }
  int iOut[iM][iN];
  int p=0,q=0;//p为圈数,q为原数组下标
  while(p<iN/2)
  {
    for(int i=p;i<iN-p-1;i++)//圈上
    {
      iOut[p][i]=iData[q++];
    }
    for(int i=p;i<iM-p-1;i++)//圈右
    {
      iOut[i][iN-p-1]=iData[q++];
    }
    for(int i=iN-p-1;i>p;i--)//圈下
    {
      iOut[iM-p-1][i]=iData[q++];
    }
    for(int i=iM-p-1;i>p;i--)//圈左
    {
      iOut[i][p]=iData[q++];
    }
    p++;
  }
  if(iN%2==1)//处理中间一列
  {
    for(int i=p;i<iM-p;i++)
    {
      iOut[i][iN/2]=iData[q++];
    }
  }
  //循环输出
  for(int i=0;i<iM;i++)
  {
    for(int j=0;j<iN;j++)
    {
      if(i==0&&j==0)
      {
        printf("%d",iOut[i][j]);
      }
      else if(j==0)
      {
        printf("\n%d",iOut[i][j]);
      }
      else
      {
        printf(" %d",iOut[i][j]);
      }
    }
  }
  return 0;
}

错误分析:

1.奇数的中间一列无法界定上下左右,感觉逻辑基础不同,暂时合并不到整体结构中去;

2.注意螺旋赋值的时候的变量意义,都与圈数有关,不能出现无关圈数的元素;

3.这样直接分段赋值的操作没有数组越界的风险,不需要更大的二维数组。

猜你喜欢

转载自blog.csdn.net/bawangtu/article/details/81275942