//是输入6就会报错,为什么?

#include<iostream>
using namespace std;
#define sizem ((size / 2 - 1) / 2)
#define sizeh (size / 2)
#define sizesq (sizeh * sizeh)

void main()
{
	int size = 0;    //魔方阵大小
	int x = 0, y = 0;        //下一个数字所放的位置
	int i, j;        //循环变量
	int st_i, st_x = 0, st_y = 0;
	int currnum;     //构造双偶数阶幻方填数的变量
	int temp;
 
	//输入幻方大小
	while ((size < 1) || (size > 31) || (size == 2))
	{
		cout <<"please input size of magic square( size>1 || size!=2 || size<31 ) :"<<endl;
		cin >>size;
	}

	//建立二维动态数组
	int **a = new int *[size];
	for (i=0; i<size; i++)
	{
		a[i] = new int [size];
	}
	
	//构造奇数(2n+1)阶幻方
	if (size % 2 == 1)
	{
		x = (size + 1) / 2 - 1;     //第一个数字在第一行的正中间位置
		y = 0;
		//填入
		for (i=1; i<=size*size; i++)
		{
			a[y][x] = i;
			//分析下一个数字的位置--当下一个数是size的倍数时,放在正下方
			if (i % size == 0)
			{
				y++;
			}
			//超出上面的边界
			else if (y == 0)
			{
				x++;
				y = size - 1;
			}
			//超出右面的边界
			else if (x == size - 1)
			{
				x = 0;
				y--;
			}
			//正常情况
			else
			{
				x++;
				y--;
			}
		}
	}
	
	//构造双偶数(4n)阶幻方
	else if (size % 4 == 0)
	{
		//分区并标记
		for (x=0; x<size/2; x++)
		{
			for (y=0; y<size/2; y++)
			{
				if ((x + y) % 2 == 0)
				{
					a[x][y] = -1;
					a[x][size-y-1] = -1;
					a[size-x-1][y] = -1;
					a[size-x-1][size-y-1] = -1;
				}
			}
		}
		//填入
		for (x=0; x<size; x++)
		{
			for (y=0; y<size; y++)
			{
				currnum = x * size + y;
				if (a[x][y] == -1)
				{
					a[x][y] = size * size - currnum;
				}
				else
				{
					a[x][y] = currnum + 1;
				}
			}
		}
	}
	
	//构造单偶数(2(2m+1))阶幻方
	else
	{
		//构造size/2阶幻方
		for (st_i=0; st_i<4; st_i++)
		{
			switch (st_i)
			{
			case 0:
				st_x = 0;
				st_y = 0;
				break;
			case 1:
				st_x = sizeh;
				st_y = sizeh;
				break;
			case 2:
				st_x = sizeh;
				st_y = 0;
				break;
			case 3:
				st_x = 0;
				st_y = sizeh;
				break;
			default:
				break;
			}
			x = (sizeh + 1) / 2 - 1;     //第一个数字在第一行的正中间位置
			y = 0;
			//填入
			for (i=1; i<=sizesq; i++)
			{
				a[y+st_y][x+st_x] = i + sizesq * st_i;
				//分析下一个数字的位置--当下一个数是size的倍数时,放在正下方
				if (i % (size / 2) == 0)
				{
					y++;
				}
				//超出上面的边界
				else if (y == 0)
				{
					x++;
					size / 2 - 1;
				}
				//超出右面的边界
				else if (x == size / 2 - 1)
				{
					x = 0;
					y--;
				}
				//正常情况
				else
				{
					x++;
					y--;
				}
			}
		}
		//交换A和D的第二行起m个数字
		for (j=1; j<sizem+1; j++)
		{
			temp = a[(sizeh+1)/2-1][j];
			a[(sizeh+1)/2-1][j] = a[(sizeh+1)/2+sizeh-1][j];
			a[(sizeh+1)/2+sizeh-1][j] = temp;
		}
		//交换A和D其它行的数字
		for (i=0; i<sizeh; i++)
		{
			if (i == (sizeh + 1) / 2 - 1)
			{
				continue;
			}
			for (j=0; j<sizem; j++)
			{
				temp = a[i][j];
				a[i][j] = a[sizeh+i][j];
				a[sizeh+i][j] = temp;
			}
		}
		//交换C和B最后m-1行的数字
		for (i=0; i<sizeh; i++)
		{
			for (j=size-1; j>size-sizem; j--)
			{
				temp = a[i][j];
				a[i][j] = a[sizeh+i][j];
				a[sizeh+i][j] = temp;
			}
		}
    }
	//输出魔方
	cout<<endl;
	for (i=0; i<size; i++)
	{
		for (j=0; j<size; j++)
		{
			cout<<a[i][j]<<" ";
		}
		cout<<endl<<endl;
	}
	cout<<endl;
	//清除数组
	for (i=0; i<size; i++)
	{
		delete [] a[i];
	}
	delete [] a;
}