我本来的想法是:每次都用新的数组去覆盖,但我写不出来。。等下次再看这道题时看看能不能写出来
然后看了一些大佬的想法,写个小总结
方法一:来自y总的想法并加了小修改~
- y总的做法是: 对于奇数 每一圈距离中心点的距离相等;
中心点 - 横纵坐标中的最大值
对于偶数:a[i][j] = n / 2 - max(min(abs(i - n / 2), abs(i - (n - 1) / 2)), min(abs(j - n / 2), abs(j - (n - 1) / 2)));
这个好像比 奇数多了一个判断min(abs(i - n / 2), abs(i - (n - 1) / 2))
,其实我没懂。。应该是种技巧吧hhh
更正:规律是每个数等于它到上下左右四条边的距离的最小值。(from yls的解答) - 我在偶数上改了一下,偶数没有中心点,那我就自己虚拟一个中心点,这个中心点就得是小数了,不影响距离~还得加上1
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 110;
int n;
int a[N][N];
int main()
{
while(cin >> n, n)
{
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n; j ++ )
{
if (n % 2)
a[i][j] = (n + 1) / 2 - max(abs(i - n / 2), abs(j - n / 2));
else
a[i][j] = (n - 1) / 2.0 - max(abs((n - 1) / 2.0 - i), abs((n - 1) / 2.0 - j)) + 1;
}
for (int i = 0; i < n; i ++ )
{
for (int j = 0; j < n; j ++ )
cout << a[i][j] << ' ';
cout << endl;
}
cout << endl;
}
return 0;
}
方法二:不用数组,找 数 和 坐标 的关系
while(cin >> n, n)
{
for (int i = 1; i <= n; i ++ )
{
for (int j = 1; j <= n; j ++ )
cout << min(min(i, j), min(n - i + 1, n - j + 1)) << ' ';
cout << endl;
}
cout << endl;
}
方法三:对称着来写(这个坐标我看了好久才想明白, 我真是笨死了)
while(cin >> n, n)
{
for (int i = 0; i < n; i ++ )
{
for (int j = i; j < n - i; j ++ )
{
a[j][i] = a[i][j] = i + 1;
a[j][n - i - 1] = a[n - i - 1][j] = i + 1;
}
}
for (int i = 0; i < n; i ++ )
{
for (int j = 0; j < n; j ++ )
cout << a[i][j] << ' ';
cout << endl;
}
cout << endl;
}
萌新这样写ac了
我一开始也是想着在数组里面直接填不就完了,但是想不出来怎么填,感谢大佬
一起加油呀
太厉害了大佬 我知道怎么做但是写不出来很尴尬、
牛逼啊!同学,为你非常认真的学习态度点赞。👍
设置中心点,然后找每圈距离中心点 隔了几圈,然后计算得到值
很妙
兄弟太牛了,跟你点个赞
我看不懂,脑子比较钝
家人们,谁能跟我讲讲第二种方法吗
可以把最外侧一圈看作一堵墙,某一点的值就是它到墙的距离,最中间距离墙最远,值最大。
赞赞赞,懂了
不太要脑子的做法
#include[HTML_REMOVED]
using namespace std;
int main()
{
int i,j,k,n;
}
对于第三种做法的说明:
关于整圈的下标,
[i][j], [j][i], [n-i-1][j], [j][n-i-1]
四个下标可以完成整圈的遍历,外层循环写为i从0到n-1,j写为从i到n-i-1。构造思路大概是在四条边以特定方向遍历整条边,所以有四个点,每个点的位置是一维变化的。这个关系来源是确定好
[i][j]
后取主对角线对称得到[j][i]
,又观察到[i][j]
和[n-i-1][j]
的关系(横坐标对称),再取主对角线对称得到所有点。理论上还可以构造四个同为逆时针方向变化的坐标,但上述构造方法浅显易懂。
啊,ε=(´ο`*)))唉哎,萌新还是看不懂
min(min是啥意思啊
看完整,i和j取最小值,n - i + 1和n - j + 1取最小值,然后再把这两个最小值取最小值,就是直接根据坐标推出来的
感觉第三种做法真的很nice
用覆盖来做
太暴力了
那个while(cin >> n, n)里面的,n)怎么理解呀?,求大佬告知
while里面的n就是一个判断的作用,即当输入的n为0时,则表示条件为假,退出循环
这个只需要考虑每个元素到四条边距离的最小值即可
orz
这样写AC了
6666
牛逼啊!!!兄弟