首页 > 其他分享 >PAT乙级1030 || 完美数列(C示例解决运行超时)

PAT乙级1030 || 完美数列(C示例解决运行超时)

时间:2024-08-12 19:25:18浏览次数:9  
标签:PAT 数列 示例 int max list num 长度 1030

完美数列

给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列。

现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。

输入格式:

输入第一行给出两个正整数 N 和 p,其中 N(≤105)是输入的正整数的个数,p(≤109)是给定的参数。第二行给出 N 个正整数,每个数不超过 109。

输出格式:

在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。

输入样例:

10 8
2 3 20 4 5 1 6 7 8 9

输出样例:

8

解题思路和分析:

题目思路很简单,这题难点在于解决超时问题,

  1. 首先第一点需要进行排序。
  2. 然后遍历数组,按照题目要求求出满足条件的最长数列,这个也简单,稍微难点的是优化遍历方法,稍后介绍。

先展示一下错误示范,也可以直接翻到最后看最终代码:

错误代码示范(C):

        因为我第一次做这道题也是没考虑到各种优化,导致超时了,记录一下我的错误时刻,

#include <stdio.h>
#include <stdlib.h>

int compare(const void * a, const void * b) {
    return * (int *) a - * (int *) b;
}

int main() {
    int N, p;  // 数列长度, 系数
    scanf("%d %d", &N, &p);
    int num[N];  // 存储数列
    int list_max = 0;  // 最大完美数列长度
    
    for (int i = 0;i < N;i++) {  // 循环读取
        scanf("%d", &num[i]);
    } 
    qsort(num, N, sizeof(int), compare);  // 排序

    for (int i = 0;i < N;i++) {
        long min_p = num[i] * p;  // 计算 最小值 * 系数 p
        int num_size = 1;  // 记录数组长度
        for (int j = i + 1;j < N;j++) {
            if ((long)num[j] <= min_p) {
                num_size++;  // 满足最小值 m * p >= 最大值 M, 数列长度 + 1
            }
        }
        if (num_size > list_max) {
            list_max = num_size;  // 更新最大长度
        }
    }
    printf("%d\n", list_max);  // 打印结果
    return 0;
} 

以上代码提交会超时,超时最大原因就是进行了没必要的查询或者计算,所以思路就来了:

  1. 第一:你会发现从数列中计算最大完美数列长度时,从第一个数到最后一个数一直都在循环判断,所以这就是重复计算了。
  2. 第二:以上问题解决之后排序算法也需要用更快的方法,我稍后调整使用的是快速排序。
  3. 第三:其实我还忽略了一点乘法结果超过int的范围,其实我考虑到了,但是没有处理好,后面也有解决。

优化后的代码(C):

        既然说了问题和思路,那我接下来就直接给出我的最终代码:

#include <stdio.h>
#include <stdlib.h>

void quicksort(int *arr,int n)
{
    if(n<2) return;
    int key=arr[0];
    int left=0;
    int right=n-1;
    int which=2;  // 2表示右移动,1表示左移动
    while(left<right)
    {
        if(which==2)
        {
            if(arr[right]>=key) {right--;continue;}
            else if(arr[right]<key)
            {
                arr[left]=arr[right];
                left++;
                which=1;
                continue;
            }
        }
        if(which==1)
        {
            if(arr[left]<=key) {left++;continue;}
            else if(arr[left]>key)
            {
                arr[right]=arr[left];
                right--;
                which=2;
                continue;
            }
        }
    }
    arr[left]=key;
    quicksort(arr,left);  //左递归
    quicksort(arr+left+1,n-left-1);  //右递归
}

int main() {
    int N;
    long p;  // 数列长度, 系数
    scanf("%d %ld", &N, &p);
    int num[N];  // 存储数列
    int list_max = 1;  // 最大完美数列长度,初始化为2是因为在初始计算num_size = list_max - 1

    for (int i = 0;i < N;i++) {  // 循环读取
        scanf("%d", &num[i]);
    } 
    quicksort(num, N);
    for (int i = 0;i < N - list_max;i++) {  // 获得最大长度之后,在数列剩余不足最大长度时最没必要计算        
        for (int j = i + list_max;j < N;j++) {
            if (num[j] <= num[i] * p) {
                list_max++;  // 满足最小值 m * p >= 最大值 M, 数列长度 + 1
            } else {
                break;
            }
        }
    }
    printf("%d\n", list_max);  // 打印结果
    return 0;
} 

以上代码两个大调整:

  1. 使用更高效的排序算法。
  2. 优化了遍历过程,减少不必要的遍历,因为题目只要求求最大完美数列,所以小于最大长度时都可以不必计算,其次我还发现只需要使用到一个记录长度的变量就行,其他都是多余的。

提交代码,答案正确,欢迎大佬指导不恰当的地方。

标签:PAT,数列,示例,int,max,list,num,长度,1030
From: https://blog.csdn.net/m0_75204116/article/details/141112403

相关文章

  • Java微信公众号推送模版消息的方法示例
    要在Java中向微信公众号推送模板消息,首先需要确保我们已经有了微信公众号,并且已经设置了模板消息权限和模板ID。模板消息是一种向用户发送通知的服务,广泛用于订单状态更新、服务提醒等场景。下面,我将详细介绍如何使用Java结合微信官方提供的API来实现模板消息的推送。这通常涉及......
  • 安装local-path-provisioner基于HostPath动态制备PV
    目录一、背景二、安装local-path-provisioner1、地址2、更改local-path-provisioner使用的默认存储路径3、创建文件并提权4、创建NameSpace5、应用local-path-storage6、验证相关资源状态三、设置local-path为defaultSC四、使用StorageClass动态制备PV1、创建PVC2、创建......
  • TI 生成 TPG 流程 Test Pattern Generator
    TI生成TPGTestPatternGenerator1.主要作用:生成各种预定义的图形和模式用来检查CSI接口的图像传输质量调试和验证使用TPG生成的测试图形可以方便地验证接口的正确性和稳定性2.代码中的体现staticconstchar*constub960_tpg_qmenu[]={ "Disabled", "1vertical......
  • 翔云PHP身份证识别接口集成示例-护照识别-港澳台通行证识别
    证件识别接口简介:证件识别接口一般是指针对各类证件进行识别,其中包含但不限于身份证识别、护照识别、港澳台通行证识别、户口页识别、驾驶证识别、行驶证识别、台湾健保卡等,其​多应用于需要进行实名认证与证件信息登记的场景。证件身份证识别接口返回结果示例如下:证件识别接......
  • docker 详细教程(通俗易懂,带有应用示例)
    1、Docker基本概念什么是Docker?Docker是一个开源的容器化平台,允许开发者封装他们的应用程序及其所有依赖项到一个标准化的单元中,这个单元被称为“容器”。容器可以在任何支持Docker的环境中运行,从而确保应用程序的可移植性和一致性。Docker的优势一致性和可移植性......
  • docker 详细教程(通俗易懂,带有应用示例)
    1、Docker基本概念什么是Docker?Docker是一个开源的容器化平台,允许开发者封装他们的应用程序及其所有依赖项到一个标准化的单元中,这个单元被称为“容器”。容器可以在任何支持Docker的环境中运行,从而确保应用程序的可移植性和一致性。Docker的优势一致性和可移植性:Docke......
  • PAT1002 写出这个数
    读入一个正整数n,计算其各位数字之和,用汉语拼音写出和的每一位数字。输入格式:每个测试输入包含1个测试用例,即给出自然数n的值。这里保证n小于10100。输出格式:在一行内输出n的各位数字之和的每一位,拼音数字间有1空格,但一行中最后一个拼音数字后没有空格。输入样......
  • PAT1001 害死人不偿命的(3n+1)猜想
    卡拉兹(Callatz)猜想:对任何一个正整数n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把(3n+1)砍掉一半。这样一直反复砍下去,最后一定在某一步得到n=1。卡拉兹在1950年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结......
  • 简单的python web项目的docker-compose.yml 示例
    一个简单的pythonweb项目,包含redis,mysql,nginx,定时业务调度等其中web启动注册了自定义命令flaskcreate-db&&flaskinit-db&&uwsgi/web/uwsgi.iniversion:'3.5'services:db:image:mysqlcontainer_name:yeping_mysqlcommand:--default-......
  • 设计模式 - Singleton pattern 单例模式
    文章目录定义单例模式的实现构成构成UML图单例模式的六种实现懒汉式-线程不安全懒汉式-线程安全饿汉式-线程安全双重校验锁-线程安全静态内部类实现枚举实现总结其他设计模式文章:最后定义单例模式是一种创建型设计模式,它用来保证一个类只有一个实例,并且提供一个......