您的位置:首页 > 其它

趣味数组(一)

2015-07-31 18:55 169 查看
首先,我们来聊一聊魔方数组。

1.魔方数组

首先,啥事魔方数组呢?例如:

6 1 8

7 5 3

2 9 4

他的每一行,每一列以及对角线的和都等于一个常数,这个常数为n*(n*n+1)/2。其中,n为阶数。

那么,我们应该怎么实现魔方数组呢?

1.我们将1安置在第一行的中间位置,及(i,j)=(1,(n+1)/2)

2.下一个数我们写到上一个数主对角线的上方,即(i1,j1)=(i-1,j-1)

3.如果在上一步中,i和j出界,则令i=n或者j=n。

4.如果,应写的位置没有出界,但是已经有数字,则将他移到下一行,但是列数不变。

代码如下:环境VS2010

<span style="font-size:24px;"><span style="font-size:24px;">	int a[100][100];
	int n;//
	scanf("%d",&n);

	int i=1;
	int j=int((n+1)/2);
	int i1,j1;
	int x=1;
	memset(a,0,sizeof(a));

	while(x<=n*n)
	{
		a[i][j]=x;
		x++;
		i1=i;
		j1=j;
		i--;
		j--;
		if (i==0)
		{
			i=n;
		}
		if (j==0)
		{
			j=n;
		}
		if (a[i][j]!=0)
		{
			i=i1+1;
			j=j1;
		}
	}
	for(i=1;i<=n;i++)
	{
			printf("\n");
		for (j=1;j<=n;j++)
		{
			printf("%4d",a[i][j]);
		}
	}
</span></span>


2.螺旋数组

啥是螺旋数组?例如:

1 8 7

2 9 6

3 4 5

这就是一个螺旋数组。那么怎么才将他输出出来的?

在这里我们采用模拟人工摆放的思路来处理螺旋数组。

让我们想想,我们是怎么手工的摆放的。

我们要将1~n*n个数,放在a

的数组中,关键是处理好行标和列标的变化范围和过程。

我们将数组的左侧和下方看做前半圈,将右侧和上方看做后半圈。使用k来表示,每一侧元素的个数。则,在前半圈,k的范围是1~2*k-1。

那么,行坐标 i和列坐标 j的变化为:

j=1 i++(1~n) k=n 左侧

i=n j++(2~n) k=n-1 下侧

j=n i--(n-1~1) k=n-1 右侧

i=1 j--(n-1~2) k=n-2 上侧

还有一个问题,我们怎么来判断前半圈还是后半圈??在这里我们设置一个变量t。当t=1,表示前半圈,t=-1,表示后半圈。

<span style="font-size:24px;">	//VS2010
        int a[100][100],b[2];
	int k;//每一层有几个数
	int t=1;//t=1在左下角,t=-1在右下角
	int x=1,y,n;
	memset(a,0,sizeof(a));
	b[0]=-1;
	b[1]=0;
	scanf("%d",&n);
	k=n;
	while(x<=n*n)
	{
		for(y=0;y<2*k-1;y++)
		{
			b[y/k]=b[y/k]+t;
			a[b[1]][b[0]]=x;
			x++;
		}
		k--;
		t=-t;
	}
	for (int i=0;i<100;i++)
	{
		for(int j=0;j<100;j++)
			if (a[i][j])
			{
				printf("%4d",a[i][j]);
			}
			printf("\n");
	}
</span>
在这里我们使用了一个数组b,这个数组是干啥的呢??

b[0]表示的行下标,b[1]表示列下标,那么为啥不直接使用i和j呢??

其中这个表达是的意义是啥?

<span style="font-size:24px;">b[y/k]=b[y/k]+t;</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: