1050. 螺旋矩阵(25)

1050. 螺旋矩阵(25)

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

输入格式:

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

输出格式:

输出螺旋矩阵。每行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的值,方法就是先计算数字总数n的平方根,依次递减,直到可以整除n,这个数就是N,M = n/N
(3)用一个二维数组表示要输出的螺旋数组结构,按照螺旋数组的规律给二维数组赋值;
(4)螺旋数组的赋值方式是:
	a.分序号递增、递减两个方向
	b.每一圈的规律是相似的,分析一下就可以得到,将这一圈的输出方式写成一个函数;
	c.每输出完一个边,检查是否已经输出完毕;
	d.对于内圈,用一个值代表外圈数量,作为边界条件计算
这样分步骤做就不会错啦~
using System;

namespace PAT
{
    class Program
    {
        static int count;
        static int M;
        static int N;
        static int[,] PrintArray;
        static int start;
        static int MIndex;
        static int NIndex;
        static void Main()
        {
            int length = int.Parse(Console.ReadLine());
            int[] numbers = GetIntArray(length);
            Array.Sort(numbers);
            //找到M和N的值
            NIndex = (int)Math.Sqrt(length); //N初始值为平方根
            while (NIndex >= 1 && length % NIndex != 0)
                NIndex--;
            MIndex = length / NIndex;

            PrintArray = new int[MIndex, NIndex];

            count = length;
            //先横着排一次
            M = MIndex;
            N = NIndex;
            

            //之后竖着排M-1,横着排N-1,然后换方向,M/N值减少1,一直到Count=0就终止
            //初始方向是增大的,用direction表示
            start = 0;
            bool direction = true;

            while (count != 0)
            {
                PrintRow(numbers, direction);
                if (count == 0)
                    break;
                PrintCol(numbers, direction);
                if (count == 0)
                    break;
                direction = !direction;
                PrintRow(numbers, direction);
                if (count == 0)
                    break;
                PrintCol(numbers, direction);
                if (count == 0)
                    break;
                direction = !direction;
                N--;
                M--;
                start++;
            }

            string msg = "";
            for (int i = 0; i < MIndex; i++)
            {
                for (int j = 0; j < NIndex; j++)
                    msg += PrintArray[i, j] + " ";
                Console.WriteLine(msg.TrimEnd());
                msg = "";
            }
        }

        static void PrintRow(int[] numbers, bool direction)
        {
            if (direction)
            {
                for (int i = start; i < N; i++)
                {
                    count--;
                    PrintArray[start, i] = numbers[count];
                }
                //if(count == 0)
            }
            else
            {
                for (int i = NIndex-2 - start; i >= start; i--)
                {
                    count--;
                    PrintArray[MIndex - start -1, i] = numbers[count];
                }
            }
        }

        static void PrintCol(int[] numbers, bool direction)
        {
            if (direction)
            {
                for (int i = start + 1; i < M; i++)
                {
                    count--;
                    PrintArray[i, NIndex - start -1] = numbers[count];
                }
            }
            else
            {
                for (int i = MIndex - start - 2; i >= start + 1; i--)
                {
                    count--;
                    PrintArray[i, start] = numbers[count];
                }
            }
        }

        static int[] GetIntArray(int length)
        {
            string[] numStr = Console.ReadLine().Split(' ');
            int[] numbers = new int[length];
            for (int i = 0; i < length; i++)
                numbers[i] = int.Parse(numStr[i]);
            return numbers;
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值