问题
欧拉发现了显着的二次方程式:
n²+ n + 41
事实证明,公式将为连续值n = 0到39产生40个素数。但是,当n = 40时,402 + 40 + 41 = 40(40 + 1)+ 41可被41整除,并且当n = 41时,41 + 41 + 41明显可被41整除。
发现令人难以置信的公式n² - 79n + 1601,它为连续值n = 0到79产生80个素数。系数-79和1601的乘积为-126479。
考虑形式的二次方:
n²+ an + b,其中| a | < 1000和| b | < 1000
其中| n |是n的模量/绝对值 例如| 11 | = 11和| -4 | = 4 找到系数a和b的乘积,用于生成连续n值的最大素数的二次表达式,从n = 0开始。
我尝试使用这种方法解决这个问题。
#include <iostream>
#include <vector>
#include <math.h>
#include <stdio.h>
#include<algorithm>
using namespace std;
#define MAX 100000000
#define rP(n) (sieve[n>>6]|=(1<<((n>>1)&31)))
#define gP(n) (sieve[n>>6]&(1<<((n>>1)&31)))
int main()
{
const int S=(int)sqrt((double)MAX);
unsigned sieve[(MAX>>6)+1]={0};
int i, j,k,l=0 ;
vector<long int>prime;
prime.push_back(2);
for(i=3;i<=S;i+=2) if(!(gP(i))) {
k=(i<<1);
//prime[l++]=i;
for(j=i*i;j<=MAX;j+=k) rP(j);
}
for(i=3;i<=MAX;i+=2)
{ if(!(gP(i)))
{prime.push_back(i);
//cout<<i<<endl;
}
}
int sum1,multi;
int f,max1=0;
long int z;
int a=-999;
int b=-999;
bool t;
for(a;a<=1000;a++)
{
for(b;b<=1000;b++)
{
sum1=0;
f=0;
t=true;
while(t)
{
z=(f*f)+(a*f)+b;
if(binary_search(prime.begin(),prime.end(),z))
sum1++;
else
t=false;
f++;
}
if(sum1>max1)
{
max1=sum1;
multi=a*b;
}
}
}
cout<<multi<<endl;
return 0;
}
它给了我错误的答案,但它给出了正确的答案,我在for循环中声明了a,b,即
for(int a=-999;a<=1000;a++)
{
for(int b=-999;b<=1000;b++)
{
sum1=0;
f=0;
t=true;
while(t)
{
z=(f*f)+(a*f)+b;
if(binary_search(prime.begin(),prime.end(),z))
sum1++;
else
t=false;
f++;
}
if(sum1>max1)
{
max1=sum1;
multi=a*b;
}
}
}
请你解释一下原因?
答案 0 :(得分:2)
使用原始代码:
int b=-999;
bool t;
for(a;a<=1000;a++)
{
for(b;b<=1000;b++)
仅初始化b
一次。内部循环完成后,外部重新启动,b
不会重新初始化,循环中的条件将为false。这意味着无论你运行外循环多少次,内循环只会运行一次。
使用新代码,每次内循环开始时都会初始化b
。