您的位置:首页 > 其它

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

2015-10-29 01:10 507 查看
最近在练习华为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;

}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: