趣味数组(一)
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
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,表示后半圈。
b[0]表示的行下标,b[1]表示列下标,那么为啥不直接使用i和j呢??
其中这个表达是的意义是啥?
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>
相关文章推荐
- [Android]可缩放性ImageView(可以放大缩小)
- 关于Talend的Patch分支对应Eclipse开发环境的配置总结.
- MFC实现的串口测试程序
- Yii 跨数据库关联关系
- 从Eclipse到Android Studio
- 精灵点点基础教程2 -- 基本操作
- git
- redis --初级笔记
- python中的getopt模块
- opencv简单滤波
- 湖南省第六届省赛有趣题
- HDU 2795 Billboard 线段树 顺序点更新
- 【模式识别】OpenCV中使用神经网络 CvANN_MLP
- 关于Excel文件过大的问题解决方案
- php将汉字转换拼音
- CXF整合Spring之JaxWsProxyFactoryBean调用
- LVM快照(snapshot)备份
- 在HTML网页中嵌入脚本的方式
- CDOJ 最短路
- Android 内存监测工具 DDMS --> Heap