您的位置:首页 > 理论基础 > 数据结构算法

螺旋矩阵

2016-07-02 09:52 375 查看
螺旋矩阵解释起来有点烦,但是看上去之后让人一目了然。

其实一开始对这个还是很反感的,因为特别难控制。

但是参考了http://www.cnblogs.com/eshizhan/archive/2010/06/01/1749013.html之后,其实发现也就这么回事儿。

#include<bits/stdc++.h>
using namespace std;
int ar[105][105];
int n;
void SpiralArray(int nsize)
{
int a=nsize/2*2+1;//保证边长为奇数
int y=a/2,x=a/2;//从中心点开始
for (int i=nsize*nsize; i>=1; i--) //(int i=1; i<=nsize*nsize; i++)
{
if (x<=a-y-1&&x>=y)ar[y][x++]=i;
else if (x>a-y-1&&x>y)ar[y++][x]=i;
else if (x>a-y-1&&x<=y)ar[y][x--]=i;
else if (x<=a-y-1&&x<y)ar[y--][x]=i;
}
}
void printarr()
{
if(n%2==0)
{
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
printf("%3d",ar[i][j]);
cout<<endl;
}
}

else
{
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
printf("%3d",ar[i][j]);
cout<<endl;
}
}
}
int main()
{
while(cin>>n)
{
if (n==0)break;
SpiralArray(n);
printarr();
}
return 0;
}



这种是从中心开始向外旋转的。定好了中间值。

其实看着这个挺别扭的,因为偶数的时候,说实话有点奇怪,因为它无所谓中心。

所以还可以换着一种,从外边旋转到里边。

#include<bits/stdc++.h>
using namespace std;
int n,m;
int arr[105][105];
void printar()
{
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
printf("%3d",arr[i][j]);
cout<<endl;
}
}
int main()
{
while(cin>>n>>m)
{
memset(arr,0,sizeof(arr));
int cnt=n*m;
int now=1,x=0,y=0;
while(now<cnt)
{
while(x+1<m&&!arr[y][x+1])arr[y][x++]=now++;
while(y+1<n&&!arr[y+1][x])arr[y++][x]=now++;
while(x-1>=0&&!arr[y][x-1])arr[y][x--]=now++;
while(y-1>=0&&!arr[y-1][x])arr[y--][x]=now++;
}
arr[y][x]=now;
printar();
}
return 0;
}



另外再介绍一个双螺旋矩阵。就是从中心开始双螺旋。

其实就是把握一些性质然后从边界向中心开始模拟

#include<bits/stdc++.h>
using namespace std;
int dx[4] = {1,0,-1,0};//下右上左旋转填数
int dy[4] = {0,1,0,-1};
int M[101][101];
int main()
{
int n;
while(cin >> n)
{
memset(M,0,sizeof(M));
int start = (n * n + 1) / 2;//从边界旋转至中心,易计算得start为最大值
int x = 0, y = 0, side = n - 1, dir = 0, cnt = 0;
int temp = side;
while(start > 0)
{
//cout<<start<<" "<<cnt<<" "<<side<<endl;
M[x][y] = M[n-1-x][n-1-y] = start--;//都是对称赋值
x += dx[dir];//按某一个方向填数
y += dy[dir];
cnt++;//计数

if(cnt == side)//如果填满了这一行
{
if(dir % 2 == 0)
{
if(side == temp)//最外圈
side--;
else
side -= 2 ;
}
dir = (dir + 1) % 4;//换方向
cnt = 0;//重新计数
}
}
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
printf("%3d",M[i][j]);
cout << endl;
}
}
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 技巧