螺旋矩阵

螺旋矩阵解释起来有点烦,但是看上去之后让人一目了然。

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

但是参考了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;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值