乙级|1030.完美数列

题目描述

给定一个正整数数列,和正整数p,设这个数列中的最大值是M,最小值是m,如果M <= m * p,则称这个数列是完美数列。
现在给定参数p和一些正整数,请你从中选择尽可能多的数构成一个完美数列。

输入描述

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

输出描述

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

输入例子

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

输出例子

8

我的代码

//代码没通过
#include<stdio.h> 
int main(){
    int n,i,j,t;
    long p,a[100000],min;
    scanf("%d %ld",&n,&p);
    for(i=0;i<n;i++){
        scanf("%ld",&a[i]);
    }
    for(i=0;i<n-1;i++){     //排序过于耗时间 
        for(j=i+1;j<n;j++){
            if(a[i]>a[j]){
                t=a[i];
                a[i]=a[j];
                a[j]=t;
            }
        }
    }
    min=a[0];
    for(i=1;i<n;i++){
        if(a[i]<=min*p){
            continue;
        }
        else{
            printf("%d",i);
            break;
        }
    }
    return 0;
}

我的分析

我的代码没通过的原因是超时。我写这道题的思路是将它所给的一系列数按照从小到大来排序,然后就知道了最小的那一个数,之后再在排好序的数组之中一个一个测试M<=m*p是否成立,找到最小的一个不成立的,则i就是所需要的答案。但是题目中可能会给出很多很多的数字,那么我这里的排序可能会花费相当大的时间(因为还没有学数据结构,现在只会冒泡排序),所以无法通过,等我之后学习了更高效的排序后再回来重新编写。

正确代码

//思路不同的代码
#include<stdio.h>
int main(){
    int n,m,i,t=0;
    long a[100000],p,max=0,min;
    scanf("%d %ld",&n,&p);
    for(i=0;i<n;i++){
        scanf("%ld",&a[i]);
        if(a[i]>max){    //在输入的时候先找出最大的数,减少时间
            max=a[i];
        }
    }
    if(max%p!=0){       //再找出能够满足的最小的数
        min=(max/p)+1;
    }
    else{
        min=max/p;
    }
    for(i=0;i<n;i++){
        if(a[i]<min){
            t++;       //开始计数
        }
    }
    if(p==2){         //p=2时的特殊情况
        printf("%ld",n-t+3);
    }
    else{
        printf("%d",n-t);   
    }
    return 0;
} 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容