一:题目

int   a[10][10]={...};  
要求对a进行排序,使之:  
1   每行从左到右为非减序列;  
2   每列从上到下为非减序列;



 

二:我的思路

  我的思路就是按照如下方式填数字,从左上角一直到右下角,按照四十五度的斜线一条条地填数字,这样保证下一层斜线里面的数字比上一层大。因为对于“小”来说,它右边的不比它小,它下面的也不比它小,其他的道理一样的,但是对于两个“大”来说,它们的顺序任意,它们只要比“小”大就可以了。

再给它指定一个方向就行了,先向右上,没法右上就再向左下,这样依次来,如图:




 

三:我的代码

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <iomanip>
  4 
  5 using std::cout;
  6 using std::cin;
  7 using std::endl;
  8 
  9 class ArrSort
 10 {
 11 public:
 12     explicit ArrSort(void);
 13     void sort(void);
 14     void showArr(void);
 15 
 16 private:
 17     enum {N = 10};
 18     int m_arr[N][N];
 19 };
 20 
 21 ArrSort::ArrSort(void)
 22 {
 23     for (int i = 0; i < N; i++)
 24     {
 25         for (int j = 0; j < N; j++)
 26         {
 27             m_arr[i][j] = rand() % 100;
 28         }
 29     }
 30 }
 31 
 32 void ArrSort::showArr(void)
 33 {
 34     for (int i = 0; i < N; i++)
 35     {
 36         for (int j = 0; j < N; j++)
 37         {
 38             cout<<std::left<<std::setw(4)<<m_arr[i][j];
 39         }
 40         cout<<endl;
 41     }
 42     cout<<endl;
 43 }
 44 
 45 int cmp(const void* a, const void* b) 
 46 {
 47     return *(int*)a - *(int*)b;
 48 }
 49 
 50 void ArrSort::sort(void)
 51 {
 52     //分配一维数组装原始二维数组中数
 53     int* arrData = new int[N * N];
 54 
 55     //填充一维数组
 56     int pIndex = 0;
 57     while (pIndex < N * N)
 58     {
 59         arrData[pIndex] = m_arr[pIndex / N][pIndex % N];
 60         pIndex++;
 61     }
 62 
 63     //给一维数组排序
 64     qsort(arrData, N*N, sizeof(int), cmp);
 65 
 66     //下面将排好序的一维数组中的数值填到二维数组
 67     struct Postion        //这个结构体是一个坐标,表明二维数组的下标
 68     {
 69         int x;
 70         int y;
 71     };
 72     enum Direction {TopRight, DownLeft};        //枚举表明方向
 73 
 74     pIndex = 0;
 75     Postion pos = {0, 0};
 76     Direction drct = TopRight;        //从向右上角方向开始
 77 
 78     while(true)
 79     {
 80         m_arr[pos.x][pos.y] = arrData[pIndex];
 81 
 82         pIndex++;
 83         if(pIndex == N * N)
 84             break;
 85 
 86         //下面给指向二维数组的坐标增加
 87         if (drct == TopRight)        //判断当前的方向
 88         {
 89             if(pos.y + 1 < N && pos.x -1 >=0)        //还可以向右上
 90             {
 91                 pos.y++;
 92                 pos.x--;
 93             }
 94             else        //不再可以左上就改变方向向左下吧,有三种情况,但分析了三种情况后你会发现只要if else就好了
 95             {
 96                 if (pos.y + 1 < N)
 97                     pos.y++;
 98                 else
 99                     pos.x++;
100 
101                 drct = DownLeft;        //设置方向
102             }
103         } 
104         else        //向左下
105         {
106             if (pos.y - 1 >= 0 && pos.x + 1 < N)        //还可以向左下
107             {
108                 pos.y--;
109                 pos.x++;
110             }
111             else        //不能在向左下了,这时候因为上面是两个条件,共四种组合,所以剩下三种可能
112             {
113                 if(pos.x + 1 >= N)
114                     pos.y++;
115                 else
116                     pos.x++;
117 
118                 drct = TopRight;
119             }
120         }
121     }
122 
123     delete [] arrData;
124 }
125 
126 int main(void)
127 {
128     ArrSort my;
129     my.showArr();
130     my.sort();
131     my.showArr();
132     cin.get();
133 }
View Code

代码中最重要的就是那个给二维数组按照顺序填数了,这里要注意当向左下不能再走时的掉头,有几种可能:

根据行列的奇数和偶数会有所不同,但是最多就那么三种向右上不能走下去的可能,向左下同理。这是对于情况1,2,3,其实只要一个if else就可以判断了,因为:

1:y++
2:x++
3:x++

虽然三种情况,但是也就两种判断。运行:




 

 四:更简单的方法

  其实对于这一题不必那么复杂的,其实只要把那些数字从左到右,从上到下排个序就可以了……这样不就符合题意了吗?如下:

#include <iostream>
#include <cstdlib>
#include <iomanip>

using std::cout;
using std::cin;
using std::endl;

class ArrSort
{
public:
    explicit ArrSort(void);
    void sort(void);
    void showArr(void);

private:
    enum {N = 10};
    int m_arr[N][N];
};

ArrSort::ArrSort(void)
{
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            m_arr[i][j] = rand() % 100;
        }
    }
}

void ArrSort::showArr(void)
{
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            cout<<std::left<<std::setw(4)<<m_arr[i][j];
        }
        cout<<endl;
    }
    cout<<endl;
}

int cmp(const void* a, const void* b) 
{
    return *(int*)a - *(int*)b;
}

void ArrSort::sort(void)
{/*
    //分配一维数组装原始二维数组中数
    int* arrData = new int[N * N];

    //填充一维数组
    int pIndex = 0;
    while (pIndex < N * N)
    {
        arrData[pIndex] = m_arr[pIndex / N][pIndex % N];
        pIndex++;
    }

    //给一维数组排序
    qsort(arrData, N*N, sizeof(int), cmp);

    //下面将排好序的一维数组中的数值填到二维数组
    struct Postion        //这个结构体是一个坐标,表明二维数组的下标
    {
        int x;
        int y;
    };
    enum Direction {TopRight, DownLeft};        //枚举表明方向

    pIndex = 0;
    Postion pos = {0, 0};
    Direction drct = TopRight;        //从向右上角方向开始

    while(true)
    {
        m_arr[pos.x][pos.y] = arrData[pIndex];

        pIndex++;
        if(pIndex == N * N)
            break;

        //下面给指向二维数组的坐标增加
        if (drct == TopRight)        //判断当前的方向
        {
            if(pos.y + 1 < N && pos.x -1 >=0)        //还可以向右上
            {
                pos.y++;
                pos.x--;
            }
            else        //不再可以左上就改变方向向左下吧,有三种情况,但分析了三种情况后你会发现只要if else就好了
            {
                if (pos.y + 1 < N)
                    pos.y++;
                else
                    pos.x++;

                drct = DownLeft;        //设置方向
            }
        } 
        else        //向左下
        {
            if (pos.y - 1 >= 0 && pos.x + 1 < N)        //还可以向左下
            {
                pos.y--;
                pos.x++;
            }
            else        //不能在向左下了,这时候因为上面是两个条件,共四种组合,所以剩下三种可能
            {
                if(pos.x + 1 >= N)
                    pos.y++;
                else
                    pos.x++;

                drct = TopRight;
            }
        }
    }

    delete [] arrData;*/
    qsort(m_arr, N*N, sizeof(int), cmp);
}

int main(void)
{
    ArrSort my;
    my.showArr();
    my.sort();
    my.showArr();
    cin.get();
}
View Code



 

五:总结
(1)C++输出对齐的数字:cout<<std::left<<std::setw(4)<<m_arr[i][j];

(2)我想的那种奇怪的填充数字的方式

(3)不要没想清楚、没看看还有没有更简单的方法就开始写代码。

posted on 2014-07-27 14:38  简单的信仰  阅读(517)  评论(0编辑  收藏  举报