PAT笔记 1050 螺旋矩阵 (25分)

博客详细记录了PAT编程题1050螺旋矩阵的解题思路,先将数据非递减排序,然后按照顺时针方向填入二维数组。作者遇到超时问题,参考了其他博主的AC代码并分享了修改后的解决方案。
摘要由CSDN通过智能技术生成
  • 题目
  • 思路
    • 先把数据非递增排序,按特定的格式存到二维数组,最后输出二维数组
    • 关键是按什么规则存入二维数组,这里按顺势针依次存储
    • 但是有几个运行测试点运行超时了,参考了一下其他的代码,贴一个博主的传送门 AC代码,第二份代码可以完美通过~感谢这位博主提供参考代码~
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <string.h>
using namespace std;

bool cmp(int a,int b){
    return a>=b;
}

int main(){
    int N;
    scanf("%d",&N);
    int sqr=sqrt(N);
    int arr[N];
    for(int i=0;i<N;i++){
        scanf("%d",&arr[i]);
    }
    sort(arr,arr+N,cmp); //按照非递增排序
    int row,col;
    for(int i=1;i<=sqr;i++){ //确定行数和列数
        if(N%i==0){
            col=i;
        }
    }
    row=N/col;
    int ans[100][100];
    memset(ans, 0, sizeof(ans));
    int i=1,j=1,k=0;
    while(k<N){
        //向右
        for(;j<col;j++){
            if(ans[i][j]==0){
                ans[i][j]=arr[k++];
            }
            if(ans[i][j+1]!=0){ //判断下一步是否越界
                break;
            }
        }
        //向下
        for(;i<row;i++){
             if(ans[i][j]==0){
                ans[i][j]=arr[k++];
             }
            if(ans[i+1][j]!=0){ //判断下一步是否越界
                break;
            }
        }
        //向左
        for(;j>1;j--){
             if(ans[i][j]==0){
                ans[i][j]=arr[k++];
             }
            if(ans[i][j-1]!=0){ //判断下一步是否越界
                break;
            }
        }
        //向上
        for(;i>1;i--){
             if(ans[i][j]==0){
                ans[i][j]=arr[k++];
             }
            if(ans[i-1][j]!=0){ //判断下一步是否越界
                break;
            }
        }
    }
    for(int i=1;i<=row;i++){
        for(int j=1;j<=col;j++){
            printf("%d",ans[i][j]);
            if(j!=col){
                printf(" ");
            }
        }
        printf("\n");
    }
    return 0;
}
  • 修改后的代码(还有有两个测试点超时)
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <string.h>
using namespace std;

bool cmp(int a,int b){
    return a>=b;
}

int main(){
    int N;
    scanf("%d",&N);
    int sqr=sqrt(N*1.0);
    int arr[N];
    for(int i=0;i<N;i++){
        scanf("%d",&arr[i]);
    }
    sort(arr,arr+N,cmp); //按照非递增排序
    int row,col,min=9999;
    for(int i=1;i<=sqr;i++){ //确定列数(<行数)
        if(N%i==0){
            if(N/i-i<min){
                min=N/i-i;
                col=i;
            }
        }
    }
    row=N/col;
    int ans[100][100]={0};
    memset(ans, 0, sizeof(ans));
    int i=1,j=1,k=0;
    ans[1][1]=arr[0];
    while(k<row*col-1){
        //向右
        while(j+1<=col&&!ans[i][j+1]){
            ans[i][++j]=arr[++k];
        }
        //向下
        while(i+1<=row&&!ans[i+1][j]){
            ans[++i][j]=arr[++k];
        }
        //向左
        while(j-1>0&&!ans[i][j-1]){
            ans[i][--j]=arr[++k];
        }
        //向上
        while(i-1>0&&!ans[i-1][j]){
            ans[--i][j]=arr[++k];
        }
    }
    for(int i=1;i<=row;i++){
        printf("%d",ans[i][1]);
        for(int j=2;j<=col;j++){
            printf(" %d",ans[i][j]);
        }
        printf("\n");
    }
    return 0;
}
  • 这是大紫书的ac代码
#include<bits/stdc++.h>
using namespace std; 
int a[10000][1000]={0},s[10000]; 
bool cmp(int a,int b){
    return a>b;
}
int main(){
    int n,i,j,x,y,r,c,tot,minn=9999;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&s[i]);
    }
    sort(s,s+n,cmp);
    for(i=1;i<=sqrt(n*1.0);i++)
    {
        if(n%i==0)
        {
            if(n/i-i<minn){
                minn=n/i-i;
                r=i;
            }
        }        
    }
    c=n/r;//c>r c行r列 
    a[1][1]=s[0];
    tot=0;
	x=y=1;
    while(tot < r * c-1)
    {
        while(y + 1 <= r && ! a[x][y + 1])
            a[x][++y] = s[++tot];
        while(x + 1 <= c && !a[x + 1][y])
            a[++x][y] = s[++tot];
        while(y - 1 > 0 && !a[x][y - 1])
            a[x][--y] = s[++tot];
        while(x - 1 > 0 && !a[x - 1][y])
            a[--x][y] = s[++tot];   
    }
    for(i=1;i<=c;i++){
            printf("%d",a[i][1]);
        for(j=2;j<=r;j++){
                printf(" %d",a[i][j]);
        } 
        printf("\n");
        
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值