C #, 203 202 196 193 178 байт
n=>{var r=new int[n,n];for(int o=n-2+n%2>>1,i=r[o,o]=1,c=2,w=o,h=o,b=1-2*(i%2),j;n>i++;){r[h,w+=b]=c++;for(j=0;j<i-1;++j)r[h+=b,w]=c++;for(j=0;j<i-1;++j)r[h,w-=b]=c++;}return r;}
Сохраненный байт благодаря @StefanDelport.
Сохранено 22 байта благодаря @FelipeNardiBatista.
Это работает следующим наблюдением за тем, как строятся квадраты:
Как вы можете видеть, каждый бит добавляется к предыдущему квадрату. Для четных чисел мы идем направо от того места, где мы находились, до тех пор, пока они не оказались на единицу ниже, чем у квадрата, а затем остались до конца. Нечетные числа, по сути, противоположны, мы идем налево, до тех пор, пока не окажемся на единицу выше текущей высоты, а затем до самого конца.
Полная / Отформатированная версия:
using System;
using System.Linq;
class P
{
static void Main()
{
Func<int, int[,]> f = n =>
{
var r = new int[n, n];
for (int o = n - 2 + n % 2 >> 1, i = r[o, o] = 1, c = 2, w = o, h = o, b = 1 - 2 * (i % 2), j; n > i++;)
{
r[h, w += b] = c++;
for (j = 0; j < i - 1; ++j)
r[h += b, w] = c++;
for (j = 0; j < i - 1; ++j)
r[h, w -= b] = c++;
}
return r;
};
Console.WriteLine(String.Join("\n", f(3).ToJagged().Select(line => String.Join(" ", line.Select(l => (l + "").PadLeft(2))))) + "\n");
Console.WriteLine(String.Join("\n", f(4).ToJagged().Select(line => String.Join(" ", line.Select(l => (l + "").PadLeft(2))))) + "\n");
Console.WriteLine(String.Join("\n", f(5).ToJagged().Select(line => String.Join(" ", line.Select(l => (l + "").PadLeft(2))))) + "\n");
Console.ReadLine();
}
}
public static class ArrayExtensions
{
public static T[][] ToJagged<T>(this T[,] value)
{
T[][] result = new T[value.GetLength(0)][];
for (int i = 0; i < value.GetLength(0); ++i)
result[i] = new T[value.GetLength(1)];
for (int i = 0; i < value.GetLength(0); ++i)
for (int j = 0; j < value.GetLength(1); ++j)
result[i][j] = value[i, j];
return result;
}
}
4
? Или любое четное число.