1050 螺旋矩阵 (25 point(s)) (含部分测试数据)
-
上次写的记录 未AC错误代码,仅错误思路记录 。
又把这题写了一次,因为有了之前的思路,所以直接按照思路来拆解。
在下标的推断中还是耗了不少时间,像下面这个图一样,要把每层循环的上下左右边界分别拆开,然后分别列出不同边界第一层和第二层下标的表达式,而且还要考虑,变量 m n 之间与实际下标 -1 的关系。
![image]()
推导的时候还是有点小问题,变量太多思路有点混乱。可能一次性考虑的关系还是太多了,应该先考虑不带下标和变量转换,或者先把 m n 转换成真正的下标的边界,总之先用一个统一的规则将循环运动模拟出来,再考虑转换问题。
-
下面是测试时用到一些测试数据,发现了一些边界问题。比如只有一个元素的情况(第一组数据)。或者是上边界输出完,但是下边界判断可以循环,导致原位置的数据被覆盖的问题(第二第三组数据)。
不过这两个其实都可以归结一个问题,就是判断元素是否输出完,所以在下 左边界的循环处都有一个 v != N 的判断。
1 116 37 76 20 98 76 42 53 95 60 81 58 93 30 18 15 1118 37 76 20 98 76 42 53 95 60 81 58 93 30 18 15 11 13 17
#include <bits/stdc++.h>
using namespace std;
int main() {
int N;
cin >> N;
vector<int> V(N);
for(int i = 0; i < N; i++)
cin >> V[i];
sort(begin(V), end(V), greater<int>());
// 算出m n
int n = sqrt(N);
int m = N / n;
while(m * n != N){
n--;
m = N / n;
}
// 获取循环次数
int v = 0, step = (n + 1) / 2, ans[m][n] = {0};
for(int s = 0; s < step; s++){
for(int up = s; up <= n - 1 - s; up++)
ans[s][up] = V[v++];
for(int right = 1 + s; right <= m - 2 - s; right++)
ans[right][n-1-s] = V[v++];
for(int down = n - 1 - s; down >= s && v != N; down--)
ans[m-1-s][down] = V[v++];
for(int left = m - 2 - s; left >= 1 + s && v != N; left--)
ans[left][s] = V[v++];
}
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++)
cout << (j ? " " : "") << ans[i][j];
cout << endl;
}
}

浙公网安备 33010602011771号