#include <iostream>
#include <cmath>
using namespace std;
法1:曼哈顿距离
离中心点越近的坐标,元素的数越大(或越小)-故使用曼哈顿距离
由于曼哈顿距离的原规律是:离中心越近,曼哈顿距离越小-故尝试
找规律,st 输出的元素 = ?- 曼哈顿距离(或变式如max(|i-x|,|j-y|,同样满足离中心越近越小)
int main(){
int n,a;
while(cin >> n,n){
for(int i = 0; i<n; i++){
for(int j = 0; j<n; j++){
if(n%2) cout << (n+1)/2 - max(abs(i-n/2),abs(j-n/2)) << " ";
else cout << (n+1)/2.0 - max(abs(i-(n-1)/2.0),abs(j-(n-1)/2.0)) << " ";
}
cout << endl;
}
cout << endl;
}
return 0;
}
法2:利用回字形二维数组特性,找坐标和元素大小关系
回字形二维数组特性:每层的元素大小表示层数,向中心以d=1递增,
层数=该坐标距离上下左右的边界中的距离最小值
int main(){
int n,a;
while(cin >> n,n){
for(int i = 0; i<n; i++){
for(int j = 0; j<n; j++)
cout << min(min(i+1,j+1),min(n-i,n-j))<< " "; // 求元素大小=坐标到左,上,下,右边界距离的最小值
cout << endl;
}
cout << endl;
}
return 0;
return 0;
}
#include <cstring>
// 法3:蛇形矩阵
// 数组的每圈数字呈一定规律变化-故用蛇形矩阵
int main(){
int nums[100+10][100+10],x,y,d,dx[] = {-1,0,1,0},dy[] = {0,1,0,-1};
int n;
while(cin >> n,n){
memset(nums,0,sizeof nums);
x = y = 0;
d = 1;
int cnt = 0,res = 1;
for (int i = 0 ; i<n*n;i++){
int a = x + dx[d],b = y + dy[d];
nums[x][y] = res;
if(a < 0||a >= n||b < 0||b >= n||nums[a][b]){
d = (d+1)%4;
a = x + dx[d];
b = y + dy[d];
cnt++;
if (!(cnt%4)) res ++;
}
x = a;
y = b;
}
for (int i = 0;i < n;i ++){
for(int j = 0;j < n;j ++){
cout << nums[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
return 0;
}
算法1
(暴力枚举) $O(n^2)$
blablabla
时间复杂度
参考文献
C++ 代码
blablabla
算法2
(暴力枚举) $O(n^2)$
blablabla
时间复杂度
参考文献
C++ 代码
blablabla