码迷,mamicode.com
首页 > 其他好文 > 详细

GEEK编程练习— —zigzag矩阵

时间:2016-04-22 19:40:18      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

题目

输入矩阵规模N,输出zigzag矩阵。
zigzag顺序为下图所示
技术分享

输入

5

输出

 0  1  5  6 14
 2  4  7 13 15
 3  8 12 16 21
 9 11 17 20 22
10 18 19 23 24

解析1

此方法是计算顺序位置的对应元素值。
假定i为行数,j为列数,每一条斜线下标(i+j)为常数,记为s(s=i+j)。

处理分为上三角和下三角两部分处理。

对于上三角,每一个斜线上的元素个数比上一斜线多一个,每个斜线上的第一个元素表示了该斜线之前元素的个数。运用等差数列求和公式,则每一斜线第一个元素的值为(1 + s) * s / 2。奇数斜线上,元素是向右上递增的,其上任意元素可以表示为s*(s+1)/2+j,而偶数斜线上任意元素可以表示为s*(s+1)/2+i。

对于下三角,斜线上元素的个数是递减的。反过来看可以看成是递增的,就仍然可以套用等差数列求和公式,求出剩下的元素的个数,用总元素个数减去剩下的元素个数就是当前斜线上的第一个元素值。所有元素的个数是n*n,剩下的元素个数为m * (m + 1) / 2,其中m=(n-1-i)+(n-1-j)。则该斜线的第一个元素值为n*n - m*(m+1)/2。

代码1

#include <iostream>
#include <iomanip>
#include <vector>

using namespace std;

int main()
{
    int N;
    cin >> N; //
    vector<int> vec(N*N);
    int s,m,smax = N * N;

    for(int i = 0; i < N; i++)
    {
        for(int j = 0; j < N; j++)
        {
            s = i + j;

            if(s < N)
            {
                vec[i * N + j] = s * (s + 1) / 2 + ((s % 2 == 0) ? j : i);
            }

            else
            {
                m = (N - 1 - i) + (N - 1 - j);
                vec[i * N + j] = smax - m * (m + 1) / 2 - (N - ((s % 2 == 0) ? j : i));
            }
        }
    }

    for(int i = 0; i < N; i++)
    {
        for(int j = 0; j < N; j++)
        {
            cout << setw(4) << vec[i * N + j];
        }
        cout << endl;
    }
    return 0;
}

解析2

此方法是寻找顺序元素的对应位置
zigzag矩阵中的任意元素m[i][j]的遍历走向规律分为边界走向和非边界走向

非边界走向
非边界走向情况比较简单,如果二维数组中的元素m[i][j]的横纵坐标和i+j是偶数,则遍历路径在矩阵中的走向就是右上角移动一格;否则,若i+j是奇数,则遍历路径在矩阵中的走向就是左下角移动一格。

边界走向
N为奇数时,分为上下两个三角矩阵
上三角矩阵
如果二维数组中的元素m[i][j]中坐标j是偶数,那么遍历路径在矩阵中的走向就是水平向右移动一格。
如果二维数组中的元素m[i][j]中坐标i是奇数,那么遍历路径在矩阵中的走向就是垂直向下移动一格。
下三角矩阵
如果二维数组中的元素m[i][j]中坐标j是奇数,那么遍历路径在矩阵中的走向就是水平向右移动一格。
如果二维数组中的元素m[i][j]中坐标i是偶数,那么遍历路径在矩阵中的走向就是垂直向下移动一格。

N为偶数时,
如果二维数组中的元素m[i][j]中坐标j是偶数,且i=0或者i=7,那么遍历路径在矩阵中的走向就是水平向右移动一格。
如果二维数组中的元素m[i][j]中坐标i是奇数,且j=0或者j=7,那么遍历路径在矩阵中的走向就是垂直向下移动一格。

代码2

#include <iostream>
#include <iomanip>
#include <vector>

using namespace std;

int main()
{
    int N;
    cin >> N;
    vector<int> vec(N*N);
    int x=0, y=0;

    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            vec[x * N + y] = i * N +j;

            //边界转向分为奇偶两种情况
            //奇数情况分为上下三角进行处理
            if(N % 2)
            {
                //上三角
                if ((x + y) < N - 1)
                {
                    if (x == 0 && y % 2 == 0 )
                    {
                        y++;
                        continue;
                    }

                    if (y == 0 && x % 2 == 1 )
                    {
                        x++;
                        continue;
                    }
                }
                //下三角
                else
                {
                    if (x == N - 1 && y % 2 == 1 )
                    {
                        y++;
                        continue;
                    }

                    if (y == N - 1 && x % 2 == 0 )
                    {
                        x++;
                        continue;
                    }
                }
            }

            //偶数情况可以直接处理
            else
            {
                if ((x == N - 1 || x == 0) && y % 2 == 0 )
                {
                    y++;
                    continue;
                }

                if ((y == N - 1 || y == 0) && x % 2 == 1 )
                {
                    x++;
                    continue;
                }
            }
            //非边界处理
            if ((x + y) % 2 == 0)
            {
                x--;
                y++;
            }
            else
            {
                x++;
                y--;
            }
        }
    }

    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            cout << setw(4) << vec[i * N + j];
        }
        cout << endl;
    }
    return 0;
}

GEEK编程练习— —zigzag矩阵

标签:

原文地址:http://blog.csdn.net/sin_geek/article/details/51212943

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!