螺旋一直不是很擅长没想到一遍过了。手动螺旋(bushi
r(行数)等于最接近srt(n)且大于等于sqrt(n)的因子,想到了题一半就完成了。
c(列数)等于n/行数。
最后一个测试点可以假设n是一个大素数。
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
int b[10005][105];
int main()
{
int n, r, c;
cin >> n;
vector<int>a(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
//非严格递减
sort(a.begin() + 1, a.end(), [](const int& x, const int& y) {
return x > y;
});
// 寻找最接近sqrt(n)且大于等于sqrt(n)的因子
for (int i = n; i >= sqrt(n); i--) {
if (n % i == 0) {
r = i;
}
}
c = n / r;
int d = 0, x = 1, y = 1, cnt = 1;
b[x][y] = a[cnt];
while (cnt < n)//手动螺旋矩阵
{
while (y < c && !b[x][y + 1]) {
b[x][++y] = a[++cnt];
}
while (x < r && !b[x + 1][y]) {
b[++x][y] = a[++cnt];
}
while (y > 1 && !b[x][y - 1]) {
b[x][--y] = a[++cnt];
}
while (x > 1 && !b[x - 1][y]) {
b[--x][y] = a[++cnt];
}
}
//输出结果
for (int i = 1; i <= r; i++)
{
for (int j = 1; j <= c; j++)
{
cout << b[i][j];
if (j == c) cout << endl;
else cout << ' ';
}
}
return 0;
}
方向向量(这个好,强烈推荐)
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
//方向向量
int mx[] = { 0,1,0,-1 };
int my[] = { 1,0,-1,0 };
int b[10005][105];
int r, c;
bool inmap(int x, int y)//判断是否越界
{
return x >= 1 && x <= r && y >= 1 && y <= c;
}
int main()
{
int n;
cin >> n;
vector<int>a(n + 1);
for (int i = 1; i <= n; i++){
cin >> a[i];
}
sort(a.begin() + 1, a.end(), [](const int& x, const int& y) {
return x > y;
});
for (int i = n; i >= sqrt(n); i--){
if (n % i == 0) {
r = i;
}
}
c = n / r;
int x = 1, y = 1, cnt = 1, k = 0;
b[x][y] = a[cnt];
while (cnt < n)
{
x += mx[k]; y += my[k];//朝该方向移动一次
while (!b[x][y] && inmap(x,y) ) {
b[x][y] = a[++cnt];
x += mx[k], y += my[k];
}
x -= mx[k]; y -= my[k];//退出时多移动了一次,还原!!!
k = (k + 1) % 4;
}
//输出
for (int i = 1; i <= r; i++)
{
for (int j = 1; j <= c; j++)
{
cout << b[i][j];
if (j == c) cout << endl;
else cout<<' ';
}
}
return 0;
}