PAT1050

来源:互联网 发布:吉祥邮 知乎 编辑:程序博客网 时间:2024/06/07 16:31
#include<iostream>#include<vector>#include<algorithm>#include <math.h> using namespace std;int main() {    int N;    cin >> N;    vector<int> A(N);    for (int i = 0;i<N;i++)        cin >> A[i];    //当只输入一个数时直接输出    if (N == 1)    {        cout << A[0] << endl;        return 0;    }    sort(A.begin(), A.end());    int a=sqrt(N);    while (N % a != 0) --a;    int c= N / a;    int m = c, n = a;    vector< vector<int> > B(m, vector<int>(n, 0));      int direct[] = { 0,1,2,3 }, d = 0, posD = 0;    //控制方向:向右,向下,向左,向上。      int x = 0, y = 0, posA = N-1;    while (posA>=0)    {        if ((x == m || x<0) || (y == n || y<0)|| B[x][y] != 0)//方向调转,碰到边界或者下一个数已经          {                          ++posD;            switch (d)       //之前已经超过边界一格了,所以要回退一步。              {            case 0: y--;x++;break;            case 1:x--;y--;break;            case 2:y++;x--;break;            case 3: x++;y++;break;            }            d = direct[posD % 4];        }        B[x][y] = A[posA];--posA; //往二维数组填充数据。          switch (d)   //一直往上面设定的方向行走和填充。          {        case 0: y++;break;        case 1:x++;break;        case 2:y--;break;        case 3: x--;break;        }    }    for (int h = 0;h<m;h++) //打印结果      {        for (int l = 0;l<n;l++)        {            cout << B[h][l];            if (l != n - 1)            {                cout << " ";            }        }        cout << endl;    }    return 0;}
  1. 开根号定义在math.h
  2. 当N=11*21时,开根号后得到的数一定位于m和n之间。通过递减直到余数为0
  3. 通过vector构造二维数组。
  4. 在判断是否需要调整方向时,是3个或。注意只要前面有条件为真,就不再进行后面的判断。(参考的做法使用的是内置数组,可以向前(下标为-1)越界访问,但是vector不行。所以改进将判断内容是否为0放在最后)
  5. 判断内容是否为0用于数组内层的迭代;判断x和y是否越界用于外层循环
  6. 通过dircted数组决定方向。大大减少了编程的复杂程度。
原创粉丝点击