PAT乙級 1030. 完美數列(25)


1030. 完美數列(25)

時間限制
300 ms
內存限制
65536 kB
代碼長度限制
8000 B
判題程序
Standard
作者
CAO, Peng

給定一個正整數數列,和正整數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

 第一個版本

 1 #include "stdio.h"
 2 void sort(double a[],int n);
 3 void swap(double *a,double *b);
 4  int main(int argc, char const *argv[])
 5 {
 6        double a[100010],p;
 7     int i,n;
 8     scanf("%d %lf",&n,&p);
 9     getchar();
10     for(i=0;i<n;i++)
11     scanf("%lf",&a[i]);
12     sort(a,n);
13     for(i=n-1;i>0;i--)
14     {
15         if(a[i]<=(a[0]*p))
16         {
17             break;
18         }
19 
20     }    
21     printf("%d\n",i+1 );
22     return 0;
23 }
24 void sort(double a[],int n)
25 {int i,j;
26     for(i=0;i<n;i++)
27         {for(j=i+1;j<n;j++)
28             {
29                 if(a[i]>a[j])
30                 swap(a+i,a+j);
31             }                
32         }    
33 
34 }
35 void swap(double *a,double *b)
36 {
37     double temp;
38     temp=*a;
39     *a=*b;
40     *b=temp;
41             
42 }

第二個版本

 1 #include "stdio.h"
 2 #include "stdlib.h"
 3 int cmp(void const *a,void const*b);
 4 int main(int argc, char const *argv[])
 5 {
 6        double *a,p;
 7     int i,j,n,count=0;
 8     while(~scanf("%d %lf",&n,&p))
 9     {
10         a=(double*)malloc(n*sizeof(double));
11         for(i=0;i<n;i++)
12         scanf("%lf",&a[i]);
13  
14        qsort(a,n,sizeof(double),cmp);
15        for(i=0;i<n;i++)//遍歷將a[i]作為最小值
16             for(j=i+count;j<n;j++)//
17                 {
18                 if(a[j]>(a[i]*p))
19                     break;
20                 if(j-i+1>count)
21                     count=j-i+1;
22                 }    
23        printf("%d\n",count );
24        free(a);
25     }
26     return 0;
27 }
28 int cmp(void const *a,void const*b)
29 {
30     return *((double*)a)-*((double*)b);
31 }

思路:首先p與最小數相乘可能會超出int范圍,所以這里用double,其次我們應該先將數組排序以方便計算,然后我們用雙重for循環查找,查找的思路是從第一個元素作為最小數,開始往后找最大數,直到不符合條件,記錄下此時的長度,然后將第二個元素作為最小數,再繼續找,最后比較長度的最大值並輸出,但是這樣會超時,所以我們要對她進行優化,減少不必要的循環,優化的思路如下:

首先我們同樣保持第一個for循環遍歷最小值,在第二個for循環中我們將j置為前一個元素作為最小數時候的長度,這樣就減少了小於上一次的不必要的for循環,j依然小於 N,用一個if判斷是否符合條件,用另一個if判斷此次是否大於上次的長度,比如說我們把樣例中的數據已經排好序:1 2 3 4 5 6 7 8 9 20 ,此時我們將array[0]作為最小數,依次向后遍歷,最大數j-最小數i+1即為數列的長度,最終找到8為最大的數,此時數列長度count為8,在將a[1]作為最小數的時候,我們直接將j置為1+8為9,直接比較a[1]和a[9]作為最小最大值得時候是否滿足,不滿足則a[1]最為最小數的時候並不能使數列變得更長,則繼續再看a[2],這樣等到有大於8的時候再更新,就可以

參考http://blog.csdn.net/wanmeiwushang/article/details/51456488


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM