PAT甲级 1105. Spiral Matrix (25)

本文介绍了一种算法,用于将一组正整数按非递增顺序填充到螺旋矩阵中。矩阵的行列大小需满足特定条件,文章提供了实现思路及示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

This time your job is to fill a sequence of N positive integers into a spiral matrix in non-increasing order. A spiral matrix is filled in from the first element at the upper-left corner, then move in a clockwise spiral. The matrix hasm rows and n columns, where m andn satisfy the following: m*n must be equal to N;m>=n; and m-n is the minimum of all the possible values.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N. Then the next line contains N positive integers to be filled into the spiral matrix. All the numbers are no more than 104. The numbers in a line are separated by spaces.

Output Specification:

For each test case, output the resulting matrix in m lines, each containsn numbers. There must be exactly 1 space between two adjacent numbers, and no extra space at the end of each line.

Sample Input:
12
37 76 20 98 76 42 53 95 60 81 58 93
Sample Output:
98 95 93
42 37 81
53 20 76
58 60 76


题目大意

给你n个数,将这n个数从大到小螺旋输出。

矩阵(行:row,列:col)的大小满足row*col=n,并且row>=col,并且row-col最小。

解题思路

行列的大小从sqrt(n)开始,小于等于sqrt(n)的第一个数为col,行计算可以用row=n/col。

至于螺旋输出就用一个flag标记控制方向就好。比如到了右边界就要往下走了,或者到了有数的地方也该换向了。

题是个好题,但是数据太水了。10000以下的最大素数为9973,如果用二维矩阵储存理论上最少要9973*9973的size,这肯定超内存了。但是我试了下500*500的size都能过,数据太水了。当然如果按理论来也是能解的,最简单的方法是:因为row和col已经确定了,可以将二维的转换为一维的了(i*row+col),这样只需要10000的size数组就可以了。

下面附上投机的水代码

#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cstdlib>
#include <climits>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define ll long long
const int MAXN = 10000 + 5;
const int MAXM = 100000 + 5;
const int INF = 0x7f7f7f7f;
const int dir[][2] = {0,1,1,0,0,-1,-1,0};
template <class XSD> inline XSD f_min(XSD a, XSD b) { if (a > b) a = b; return a; }
template <class XSD> inline XSD f_max(XSD a, XSD b) { if (a < b) a = b; return a; }
bool cmp(int x, int y){return x>y;}
int n, m;
int mp[500][500];///9973
int a[MAXN];

void Getdata(){
    memset(mp, 0, sizeof mp);
    for(int i=0; i<n; i++)
        scanf("%d", &a[i]);
}
void Solve(){
    sort(a, a+n, cmp);
    int col=sqrt(n);
    while(n%col){col--;}
    int row = n/col;
    int x=0, y=0, cnt=0;
    mp[x][y]=a[cnt++];
    int flag=0;
    while(cnt < n){
        int X = x + dir[flag][0], Y = y + dir[flag][1];
        if (X >= row || X < 0 || Y >= col || Y < 0 || mp[X][Y]) flag=(flag+1)%4;
        x += dir[flag][0], y += dir[flag][1];
        ///printf(" %d %d\n", x, y);
        mp[x][y] = a[cnt++];
    }
    for(int i=0; i<row; i++){
        for(int j=0; j<col; j++)
            printf("%d%c", mp[i][j], j==(col-1)?'\n':' ');
    }
}
int main(){
    while(~scanf("%d", &n)){
        Getdata();
        Solve();
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值