在给定的区间范围内找出所有素数能构成的最大的等差数列(即等差数列包含的素数个数最多)

最近在练习华为OJ,进过4个小时奋斗和各位前辈的指点,60分侥幸通过测试。

需要特别考虑:数列长度相等时,要输出公差大的。(也许最后一项最大的也行)

代码如下,请各位大侠指点下,为何只能到了60分

方法名称

圈复杂度

语句数

最大嵌套深度

调用次数

GetMaxArray()

23

48

5

2

main()

2

6

2

0


思路:

1. 找到数据中所有的素数并保存到新的动态数组中。

2. 以每一个素数为数列首项,对不同的公差,在这些素数中寻找数列并统计数列的长度,并记录最大长度数列的首项,公差,长度。其中公差采用数列首项与后面可能的第二项之差值,进行比较,较少公差的比较次数。

3. 输出该数列


#include <math.h>


#include <iostream>


 


using namespace std;


 


struct Num


{


       int number;


       int tag;


};


 


int GetMaxArray( int m,  int n)  //m<n,输出区间素数所组成的最长等比数列


{


      


       int N = n-m, PrimeCount;


       Num*a;


       PrimeCount= N+1;


       a= new Num[N+1];


       if(!a)


              return 0;


 


   for(int i=0; i<N+1; i++)  //对素数进行标记,true


   {      


          a[i].number = m+i;


          a[i].tag = 1; //假设为素数


                 if(a[i].number<=1 || (a[i].number%2 == 0 && (a[i].number != 2)))


          {


                 a[i].tag=0; // 非素数


                 PrimeCount--;


          }


          for(int j=3; j<=sqrt(double(m+i));j=j+2)


                 if(a[i].number%j== 0 && (a[i].number != j) && a[i].tag == 1)


                 {


                        a[i].tag = 0;  // 非素数


                        PrimeCount--;


                 }


//           cout << a[i].number <<" ";


   }


 


   int *p = new int[PrimeCount];


   if(!p)


              return 0;


   int k =0;


   for(int i=0; i<N+1; i++) //m~n素数数组


          if(a[i].tag  == 1)


          {


                 p[k] = a[i].number;


                 k++;


          }


   //for(int i=0;i<j; i++)


       //   cout <<p[i]<< " ";


   delete [] a;


   int count=0,d = 0;


   intLargeCount = 0,LargeCountD=0 , a1=0;


   for(int i=0; i<PrimeCount-1; i++) // 每个素数开始的数列,针对不同的公差进行判断


   {


//      cout << " \n the " << i << "Cycle:  a1 = " << p[i] <<"   LargeCount= " <<LargeCount << endl;


          intn=1; 


          d = p[i+n] - p[i];


//      cout << endl<< "  公差d" << d  << "-----";


          count = 2;  


          while( d<= N/2  && (i+n+1) <PrimeCount )


          {


                 for(int j = i+n+1; j<PrimeCount; j++)


                     {


                                   if((p[j] - p[i]) == count*d)


                                   {


                                          count++;


//                                       cout<< p[j] << " ";


                                   }


                                   else


                                          continue;


                 } 


//             cout << "   count forthis d is : " << count << endl;


                 if(LargeCount< count || (LargeCount == count && d > LargeCountD))  /*标记最大数列的首项,公差,数列长度*/


                 {


                        LargeCount = count;


                        a1 = p[i];


                        LargeCountD = d;       


//                         cout << "\nLargeCount < count= " << LargeCount << "; LargeCountD=" << LargeCountD << ";  a1= " << a1 << endl;


                 }


                 n++;  //数列第二项


                 d = p[i+n] - p[i];  //新的公差,以相近两项素数差为起始公差,减少运算次数


//             cout << endl<< "   公差d= " <<d  << "------";


                 count = 2; //基于新的公差,数列项序号至少为


          }


   }


//   cout << endl << endl <<endl;


   for(int i = 0; i<LargeCount; i++)


          cout << a1 +i*LargeCountD <<endl;


   delete [] p;


   return 1;


}


 


int main()


{


       int m = 0, n= 0;


       cin>> m >> n;


       int result = GetMaxArray( m,  n);


       if( result ==0 )


              cout<< " Memory issue";


       return 0;


}





猜你喜欢

转载自blog.csdn.net/zhang_fei_fresh/article/details/49481409