Skip to content

11021: 【原1021】从前有座山

题目

题目描述

author: 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1021

Description

从前有座山,山的俯视图是一个\(n \times n\)的矩形,\( (1,1) \)位置海拔最低为\(1\),然后海拔沿环形依次升高。

给定n的值,输出这座山的海拔高度图。

Input Format

输入仅有一行,为一个正整数\(n\)。

Output Format

输出为这座山的海拔高度图。

Sample Input

4

Sample Output

     1     2     3     4
    12    13    14     5
    11    16    15     6
    10     9     8     7

Hint

首先程序#include <iomanip>

假设要输出a,将cout << a改成cout << setw(6) << a

Limits

对于20%的数据,\( N<10 \)

对于100%的数据,\( N\le 150 \)

FineArtz's solution

/* 从前有座山 */
#include <iostream>
#include <iomanip>
using namespace std;

inline long long min(long long a, long long b, long long c, long long d){
    long long ret = a;
    if (ret > b) ret = b;
    if (ret > c) ret = c;
    if (ret > d) ret = d;
    return ret;
}

long long step(long long n, long long x, long long y){
    if (y == 1) return x - 1;
    if (x == n) return n + y - 2;
    if (y == n) return n * 3 - x - 2;
    if (x == 1) return n * 4 - y - 3;
    long long k = min(x - 1, y - 1, n - x, n - y);
    return 4 * k * (n - k) + step(n - 2 * k, x - k, y - k);
}

int main(){
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i){
        for (int j = 1; j <= n; ++j){
            cout << setw(6) << step(n, j, i) + 1;
        }
        cout << endl;
    }
    return 0;
}

ligongzzz's solution

#include "iostream"
#include "iomanip"
using namespace std;

constexpr auto maxNum = 200;

int main() {
    int num;
    cin >> num;

    int data[maxNum][maxNum] = { 0 };

    //爬虫方向
    int dx = 1, dy = 0;
    //点位
    int px = 1, py = 1;
    //状态
    bool status = true;

    for (int i = 1; i <= num*num; i++) {
        //画下该点
        data[px][py] = i;
        //判断是否走出
        if (px + dx > num || py + dy > num || data[px + dx][py + dy] != 0||px+dx<1||py+dy<1) {
            if (dx == 1 && dy == 0) {
                dx = 0;
                dy = 1;
            }
            else if (dx == 0 && dy == 1) {
                dx = -1;
                dy = 0;
            }
            else if (dx == -1 && dy == 0) {
                dx = 0;
                dy = -1;
            }
            else {
                dx = 1;
                dy = 0;
            }
        }
        //前进
        px += dx;
        py += dy;
    }

    for (int i = 1; i <= num; i++) {
        for (int j = 1; j <= num; j++) {
            cout << setw(6) << data[j][i];
        }
        cout << endl;
    }

    return 0;
}

Neight99's solution

#include <iomanip>
#include <iostream>

using namespace std;

void go(int, int **);
bool stop(int, int **);

int main() {
    int n;
    cin >> n;

    int **mountain = new int *[n];
    for (int i = 0; i < n; i++) {
        mountain[i] = new int[n];
        for (int j = 0; j < n; j++) {
            mountain[i][j] = 0;
        }
    }

    go(n, mountain);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cout << setw(6) << mountain[i][j];
        }
        cout << endl;
    }

    for (int i = 0; i < n; i++) {
        delete[] mountain[i];
    }
    delete[] mountain;

    return 0;
}

void go(int n, int **mountain) {
    int turn = 0, x = 0, y = 0, count1 = 1;
    while (stop(n, mountain)) {
        if (turn == 0) {
            while (y < n && mountain[x][y] == 0) {
                mountain[x][y] = count1;
                count1++;
                y++;
            }
            y--;
            turn = 1;
        } else if (turn == 1) {
            x++;
            while (x < n && mountain[x][y] == 0) {
                mountain[x][y] = count1;
                count1++;
                x++;
            }
            x--;
            turn = 2;
        } else if (turn == 2) {
            y--;
            while (y >= 0 && mountain[x][y] == 0) {
                mountain[x][y] = count1;
                count1++;
                y--;
            }
            y++;
            turn = 3;
        } else if (turn == 3) {
            x--;
            while (x >= 0 && mountain[x][y] == 0) {
                mountain[x][y] = count1;
                count1++;
                x--;
            }
            x++;
            y++;
            turn = 0;
        }
    }
}

bool stop(int n, int **mountain) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (mountain[i][j] == 0) {
                return 1;
            }
        }
    }
    return 0;
}

q4x3's solution

/**
 * 模拟
 **/
#include <iostream>
#include <iomanip>

using namespace std;

int n, a[151][151], tot = 1, x, y;
int main()
{
    cin >> n;
    a[0][0] = 1;
    while (tot < n * n) {
        while (y + 1 < n && !a[x][y + 1]) a[x][++ y] = ++ tot;
        while (x + 1 < n && !a[x + 1][y]) a[++ x][y] = ++ tot;
        while (y > 0 && !a[x][y - 1]) a[x][-- y] = ++ tot;
        while (x > 0 && !a[x - 1][y]) a[-- x][y] = ++ tot;
    }
    for (int i = 0;i < n;++ i) {
        for (int j = 0;j < n;++ j)
            cout << setw(6) << a[i][j];
        cout << endl;
    }
    return 0;
}

skyzh's solution

#include <cstdio>
#include <iostream>
using namespace std;

int map_data[150][150];

int main() {
    int n;
    cin >> n;
    int x = 0, y = 0;
    int x1 = 0, x2 = n - 1, y1 = 0, y2 = n - 1;
    for (int t = 0; t < n * n;) {
        for (int i = x1; i <= x2; i++) map_data[y1][i] = ++t;
        ++y1;
        for (int i = y1; i <= y2; i++) map_data[i][x2] = ++t;
        --x2;
        for (int i = x2; i >= x1; i--) map_data[y2][i] = ++t;
        --y2;
        for (int i = y2; i >= y1; i--) map_data[i][x1] = ++t;
        ++x1;
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%6d", map_data[i][j]);
        }
        printf("\n");
    }
    return 0;
}

victrid's solution

#include <iomanip>
#include <iostream>

using namespace std;
inline int& min(int& s1, int& s2) {
    return s1 < s2 ? s1 : s2;
}
int calc(int i, int j, int n) {
    int p = min(min(i, n + 1 - i), min(j, n + 1 - j));
    if (i == p)
        return j - i + 1 + 4 * (n - p + 1) * (p - 1);
    if (i == n + 1 - p)
        return 3 * n - j - 5 * p + 4 * (n - p + 1) * (p - 1) + 4;
    if (j == p)
        return j - i + 4 * n - 8 * p + 4 * (n - p + 1) * (p - 1) + 5;
    else
        return i + n - 3 * p + 4 * (n - p + 1) * (p - 1) + 2;
}
int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        if (i)
            cout << endl;
        for (int j = 0; j < n; j++) {
            cout << setw(6) << calc(i + 1, j + 1, n);
        }
    }
    return 0;
}

yyong119's solution

#include <iostream>
#include <cstring>
#include <iomanip>
int n,num,x,y,i,j;
int m[151][151];
int main(){
    using namespace std;
    memset(m,0,sizeof(m));
    cin>>n; m[1][n+1]=1; m[n+1][n]=1; m[n][0]=1;
    x=1; y=1; m[x][y]=1; num=1;
    while (num<n*n){
        while (m[x][y+1]==0){
            y++; num++; m[x][y]=num;
        }
        while (m[x+1][y]==0){
            x++; num++; m[x][y]=num;
        }
        while (m[x][y-1]==0){
            y--; num++; m[x][y]=num;
        }
        while (m[x-1][y]==0){
            x--; num++; m[x][y]=num;
        }
    }
    for (i=1; i<=n; i++){
        for (j=1; j<=n; j++) cout<<setw(6)<<m[i][j];
        cout<<endl;
    }
    return 0;
}