# 11021: 【原1021】从前有座山

### 题目描述

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

## Sample Input

4


## Sample Output

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


## 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;
}