鱼C论坛

 找回密码
 立即注册
查看: 3210|回复: 14

题目27:找出为连续数字产生最多质数的二次公式

[复制链接]
发表于 2015-4-23 16:44:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 欧拉计划 于 2023-10-16 02:06 编辑
Quadratic primes

1.png

题目:

欧拉曾发表过一个著名的二次公式:

1.png

这个公式对于0到39的连续数字能够产生 40 个质数。但是当 n = 40 时, 2.png 能够被 41 整除。当 n = 41 时, 3.png 显然也能被 41 整除。

利用计算机,人们发现了一个惊人的公式: 4.png 。这个公式对于 n = 0 到 79 能够产生 80 个质数。这个公式的系数,-79 和 1601 的乘积是 -126479。

考虑如下形式的二次公式:

5.png

其中 |n| 表示 n 的绝对值。

例如, |11| = 11, |-4| = 4

对于能够为从 0 开始的连续的 n 产生最多数量的质数的二次公式,找出该公式的系数乘积。

评分

参与人数 1荣誉 -1 鱼币 -1 贡献 -1 收起 理由
a1351468657 -1 -1 -1 题目:欧拉曾发表过一个著名的二次公式: .

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-8-7 11:08:34 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-9-1 16:10:20 | 显示全部楼层
  1. import math
  2. def prime(x):
  3.       if x > 2:
  4.             if x % 2 == 0:
  5.                   return False
  6.             if x == 2:
  7.                   return True
  8.             for i in range(3,int(math.sqrt(x))+1,2):
  9.                   if x % i == 0:
  10.                         return False
  11.             return True
  12.       return False
  13. list2 = []
  14. for i in range(-999,1000):
  15.       for j in range(-999,1000):
  16.             count = 0
  17.             list1 = []
  18.             while True:
  19.                   if prime(count**2+i*count+j):
  20.                         list1.append(count)
  21.                         count += 1
  22.                   else:
  23.                         break
  24.                   
  25.             if list1 not in list2:
  26.                   list2.append(list1)
  27. first = 0
  28. for each in list2:                  #得到list2之后遍历列表找到最长的一项
  29.       if first < len(each):   
  30.             first = len(each)
  31. print(first)                        
复制代码

得到最长的时候是71个连续的数 从0到70
  1. import math
  2. def prime(x):
  3.       if x > 2:
  4.             if x % 2 == 0:
  5.                   return False
  6.             if x == 2:
  7.                   return True
  8.             for i in range(3,int(math.sqrt(x))+1,2):
  9.                   if x % i == 0:
  10.                         return False
  11.             return True
  12.       return False
  13. list2 = []
  14. for i in range(-999,1000):
  15.       for j in range(-999,1000):
  16.             count = 0
  17.             list1 = []
  18.             while True:
  19.                   if prime(count**2+i*count+j):
  20.                         list1.append(count)
  21.                         if count == 70:   #根据得到的first得到i和j
  22.                               print(i,j)   
  23.                         count += 1
  24.                   else:
  25.                         break
  26.                   
  27.             if list1 not in list2:
  28.                   list2.append(list1)
  29. first = 0
  30. for each in list2:                  #得到list2之后遍历列表找到最长的一项
  31.       if first < len(each):   
  32.             first = len(each)
  33. print(first)
复制代码

得到a=-61 b=971
答案是-59231
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-19 08:55:59 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2016-10-10 22:56 编辑

根据题目的已知条件推断,n最长不可能超过题目中的79,所以只有计算0~79即可。
另外当n=0时,得b必然是要质数。所以列出1000以内的质数供判断。
再来看a,必然是奇数,而且只可能在-b与b之间。
71 -61 971 -59231
[Finished in 2.1s]
  1. def getPrime(n):
  2.         primes = [True]*n
  3.         primes[0],primes[1]=False,False
  4.         for (i, prime) in enumerate(primes):
  5.                 if prime:
  6.                         for j in range(i*i,n,i): primes[j] = False
  7.         return [k for (k,trueprime) in enumerate(primes) if trueprime]

  8. def judgePrime(n):
  9.         testlist = getPrime(int(n**0.5+1))
  10.         for each in testlist:
  11.                 if n%each == 0:
  12.                         return False
  13.         return True

  14. blist = getPrime(1000)
  15. countmax = 0
  16. for b in blist:
  17.         for a in range(-b,b,2):
  18.                 count = 0
  19.                 for n in range(80):
  20.                         if n*n+a*n+b <2: break
  21.                         else:
  22.                                 if judgePrime(n*n+a*n+b): count += 1
  23.                                 else: break
  24.                 if countmax < count:
  25.                         countmax, maxa, maxb = count, a, b
  26. print (countmax,maxa,maxb,maxa*maxb)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-12 16:21:44 | 显示全部楼层
  1. # encoding:utf-8
  2. # n**2 + a*n + b 找到得到连续素数最多的a、b系数
  3. from time import time
  4. from math import sqrt
  5.       
  6. def getPrimes(N):
  7.     primes = [True] * N
  8.     primes[0], primes[1] = False, False
  9.     for i, prime in enumerate(primes):
  10.         if prime:
  11.             for j in range(i * i, N, i):
  12.                 primes[j] = False
  13.     return [k for k, p in enumerate(primes) if p]
  14. def isPrime(N, prime_list):
  15.     sqr = sqrt(N) + 1
  16.     for t in prime_list:
  17.         if N % t == 0:
  18.             return False
  19.         if t > sqr:
  20.             break
  21.     return True
  22. def euler027():
  23.     prime_list = getPrimes(1000)
  24.     count_max = 0
  25.     for b in prime_list:
  26.         for a in range(-b, b, 2):
  27.             count = 0
  28.             for n in range(80):
  29.                 t = n ** 2 + a * n + b
  30.                 if t < 2:
  31.                     break
  32.                 else:
  33.                     if isPrime(t, prime_list):
  34.                         count += 1
  35.                     else:
  36.                         break
  37.             if count_max < count:
  38.                 count_max, max_a, max_b = count, a, b
  39.     print(count_max, max_a, max_b)
  40. if __name__ == '__main__':
  41.     start = time()
  42.     euler027()
  43.     print('cost %.6f sec' % (time() - start))

复制代码



学习了4楼老大的方法  感谢~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-23 11:10:30 | 显示全部楼层
此代码使用matlab编程
Problem27所用时间为16.7542秒
Problem27的答案为-59231
  1. %% Problem27
  2. % 题目27:找出能够带入连续数字得到最多质数的二次公式n&#178;+an+b
  3. %细节:将0带入,得到b必为质数,且大于0
  4. %将1带入,得到a+b+1为质数,a为奇数数,且-b<a<b
  5. function Output=Problem27(Input)
  6.   tic
  7. if nargin==0
  8. Input=1000;
  9. end
  10. b=[];
  11. for ii=Input:-1:3
  12.     if isprime(ii)==1
  13.         Temp=[b,ii];%b为1000以下的质数
  14.         b=Temp;
  15.     end
  16. end
  17. Num=0;
  18. Max=0;
  19. n=0;
  20. Flag=1;
  21. for jj=b
  22.     Temp=jj;
  23.     a=-jj:2:jj;
  24.     for kk=a
  25.         while (Flag==1)
  26.             if n^2+kk*n+jj>0&&isprime(n^2+kk*n+jj)==1
  27.                 Num=Num+1;
  28.                 n=n+1;
  29.             else
  30.                 Flag=0;
  31.             end
  32.         end
  33.         if Num>Max
  34.             Max=Num;
  35.             A=jj;
  36.             B=kk;
  37.         end
  38.         Flag=1;
  39.         Num=0;
  40.         n=0;
  41.     end
  42. end
  43. Output=A*B;
  44. toc
  45. disp('此代码使用matlab编程')
  46. disp(['Problem27所用时间为',num2str(toc),'秒'])
  47. disp(['Problem27的答案为',num2str(Output)])
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-18 21:32:30 | 显示全部楼层
  1. def isprime(x):
  2.     if x<=1:return 0
  3.     else:
  4.         for i in range(2,int(x**0.5)+1):
  5.             if not x%i:return 0
  6.         return 1

  7. temp=a=b=0
  8. for i in range(-999,1000):
  9.     for j in range(-999,1000):
  10.         n=0
  11.         f=j
  12.         while isprime(f):
  13.             n+=1
  14.             f=n**2+i*n+j
  15.         if temp<n:
  16.             temp=n
  17.             a=i
  18.             b=j
  19. print(a*b,a,b,temp)
复制代码

-59231 -61 971 71
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-29 07:53:51 | 显示全部楼层
  1. public class Quadratic{
  2.         public static void main(String[] args){
  3.                 int a = -1000,b = -1000,result = 0,n = 0;
  4.                 int count = 0,countmax = 0;
  5.                 int amax = 0,bmax = 0;
  6.                 for(a = -1000;a <= 1000;a ++){
  7.                         for(b = -1000;b <= 1000;b ++){
  8.                                 count = 0;
  9.                                 for(n = 0;;n ++){
  10.                                         result = n*n+a*n+b;
  11.                                         if(Prime(result)){
  12.                                                 count ++;
  13.                                         }
  14.                                         else{
  15.                                                 break;
  16.                                         }
  17.                                 }
  18.                                 if(countmax < count){
  19.                                         amax = a;
  20.                                         bmax = b;
  21.                                         countmax = count-1;
  22.                                 }
  23.                         }
  24.                 }
  25.                 System.out.println(amax+"\t"+bmax+"\t"+countmax+"\t");
  26.                 System.out.println("所求最大乘积为"+(amax*bmax));
  27.         }
  28.         public static boolean Prime(int result){
  29.                 boolean flag =true;
  30.                 for(int i = 2;i < Math.sqrt(Math.abs(result));i ++){
  31.                         if(result % i == 0){
  32.                                 flag = false;
  33.                                 break;
  34.                         }
  35.                 }
  36.                 return flag;
  37.         }
  38. }
复制代码

-61     971     71
所求最大乘积为-59231
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-12 13:23:09 | 显示全部楼层
最大连续质数:71
方程:n**2 + -61*n + 971
a*b:59231
用时: 4.5708293 秒
  1. import math
  2. import time


  3. def is_prime(num):
  4.     if num == 2 or num == 3:
  5.         return True
  6.     elif num < 0 or num == 1 or not num % 2 or not num % 3:
  7.         return False
  8.     else:
  9.         for i in range(2, int(math.sqrt(num))+1):
  10.             if not num % i:
  11.                 return False
  12.         return True

  13. result = {}
  14. for a in range(-1000, 1000):
  15.     for b in range(-1000, 1000):
  16.         ix = 0
  17.         while is_prime(ix**2 + a*ix + b):
  18.             ix += 1
  19.         result[ix] = (a, b)

  20. print("最多产生连续质数:{} 个\n对应方程:N**2 + {}*N + {}\na*b:{}".format(
  21.     max(result),
  22.     result[max(result)][0], result[max(result)][1],
  23.     abs(result[max(result)][0]*result[max(result)][1])))

  24. print("用时: {} 秒".format(time.process_time()))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-7-23 16:17:23 | 显示全部楼层
本帖最后由 永恒的蓝色梦想 于 2019-8-3 21:10 编辑
  1. from time import process_time as t
  2. t1=t()
  3. from math import sqrt
  4. def isprime(x):
  5.     if x in(2,3):return True
  6.     if x<4 or x%2==0 or(x%6!=1 and x%6!=5):return False
  7.     for i in range(3,int(sqrt(x)+1),2):
  8.         if x%i==0:return False
  9.     return True
  10. l=(0,0,0)
  11. for a in range(-999,1000):
  12.     for b in range(-999,1000):
  13.         for n in range(1,9999):
  14.             if not isprime(n**2+a*n+b):break
  15.         if n>l[2]:l=(a,b,n)
  16. print(f'运行结果:{l[0]*l[1]}\n运行时间:{t()-t1}s')
复制代码
运行结果:-59231
运行时间:6.640625s
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-6 10:43:20 | 显示全部楼层
-59231

Process returned 0 (0x0)   execution time : 0.212 s
Press any key to continue.
参考了4#的思路,然鹅只推出b为奇质数……
只好枚举
  1. #include<iostream>
  2. #include<cmath>
  3. #include<cstdlib>
  4. using namespace std;

  5. const int M = 1000;
  6. const int INF = 1e6;
  7. int cnt = 0;
  8. bool prime[M];
  9. int factor[M];

  10. void euler_sieve(){
  11.   prime[1] = false;
  12.   for (int i = 2;i <= M;i++) prime[i] = true;

  13.   for (int i = 2;i <= M;i++){
  14.     if (prime[i]) factor[++cnt] = i;
  15.     for (int j = 1;j <= cnt && i*factor[j] < M;j++){
  16.       prime[i*factor[j]] = false;
  17.       if (i % factor[j] == 0) break;
  18.     }
  19.   }
  20. }

  21. bool isprime(int x){
  22.   x = abs(x);
  23.   if (x == 0 || x == 1) return false;
  24.   for (int i = 1;factor[i] <= sqrt(x);i++)
  25.     if (x % factor[i] == 0)  return false;
  26.   return true;
  27. }

  28. void tst(){
  29.   for (int i = 0;i < cnt;i++) cout << factor[i] << "*";
  30.   cout << endl;
  31. }

  32. int main(){
  33.   euler_sieve();
  34.   //tst();
  35.   int ab;
  36.   int max_len = 0;

  37.   for (int a = -1000 + 1;a < 1000;a++){
  38.     for (int i = 2;factor[i] < 1000;i++){
  39.       int b = factor[i];

  40.       for (int n = 1;n < 80;n++){
  41.         int fx = n*n + a*n + b;
  42.         if (!isprime(fx)){
  43.           if (n > max_len)  {//cout << a << " " << b << " " << n << endl;
  44.             ab = a*b;  max_len = n;
  45.           }
  46.           break;
  47.         }
  48.       }

  49.       for (int n = 1;n < 80;n++){
  50.         int fx = n*n + a*n - b;
  51.         if (!isprime(fx)){
  52.           if (n > max_len)  {//cout << a << " " << -b << " " << n << endl;
  53.             ab = a*b;  max_len = n;
  54.           }
  55.           break;
  56.         }
  57.       }
  58.     }
  59.   }
  60.   //cout << max_len << " ";
  61.   cout << ab << endl;
  62. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-3-12 17:13:15 | 显示全部楼层
本帖最后由 a1351468657 于 2021-3-12 19:02 编辑
  1. #include <stdio.h>
  2. #include <math.h>

  3. int check_prime(int n);
  4. int check_prime(int n)
  5. {
  6.         int i, k;
  7.         k = sqrt(n + 1);
  8.         for (i = 2; i <= k; i++)
  9.         {
  10.                 if (n % i == 0)
  11.                 {
  12.                         return 0;
  13.                 }
  14.         }
  15.         return 1;
  16. }

  17. main()
  18. {
  19.         int i, j, n, a, b[200], e = 1, flag;
  20.         int max = 0, x, y;
  21.         b[0] = 2;
  22.         for (i = 3; i < 1000; i++)//根据公式b一定是小于1000的质数
  23.         {
  24.                 flag = check_prime(i);
  25.                 if (flag == 1)
  26.                 {
  27.                         b[e++] = i;
  28.                        
  29.                 }
  30.         }
  31.        
  32.         for (a = 0; a < 1000; a++)
  33.         {
  34.                 for (i = 0; i < e; i++)
  35.                 {
  36.                         n = 1;
  37.                         while (1)
  38.                         {
  39.                                 j = n * n - a * n + b[i];
  40.                                 if (j < 0)
  41.                                 {
  42.                                         break;
  43.                                 }
  44.                                 flag = check_prime(j);

  45.                                 if (flag == 0)
  46.                                 {
  47.                                         break;
  48.                                 }
  49.                                 n++;
  50.                         }
  51.                         if (max < n)
  52.                         {
  53.                                 max = n;
  54.                                 x = a;
  55.                                 y = i;
  56.                         }               
  57.                 }
  58.         }
  59.         printf("%d, %d, %d", max, x, b[y]);//x保存最大时a的值,y保存b的当时的下标       
  60. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-17 19:47:04 | 显示全部楼层
#找出为连续数字产生最多质数的二次公式
from math import *
from time import *
def is_prime(number):
    if number > 1:
        if number == 2:
            return True
        if number % 2 == 0:
            return False
        for a in range(3,int(sqrt(number) + 1),2):
            if number % a == 0:
                return False
        return True
    return False

start = time()
#当n == 0 时 b一定是质数
b_list = []
for i in range(1000):
    if is_prime(i) and i > 79:
        b_list.append(i)
#print(b_list)
#print(len(b_list))

a = -999
ab_list = []
while True:
    for b in b_list:
        if is_prime(1 + a + b):
            ab_list.append((a, b))   
    a += 1
    if a == 999:
        break
n = 0
index = 0
numlist = [0]
index_list = []
length = len(ab_list)
while index < length:
    if is_prime((n**2) + (n*ab_list[index][0]) + ab_list[index][1]):
        n += 1
    else:
        numlist.append(n)
        index_list.append(index)
        index += 1
        n = 0
        if index == length -1:
            break
index = numlist.index(max(numlist)) - 1 #第n个数是最大的  索引从0开始
#print(ab_list[index])
result = ab_list[index][0] * ab_list[index][1]
end = time()
print("可以连续产生%d个质数" % max(numlist))
print("系数a:%d, 系数b:%d" % (ab_list[index][0], ab_list[index][1]))
print("系数的乘积为:%d" % result)
print("用时:%.2f s" % (end - start))

'''   


#验证

for i in range(71):
    if is_prime((i ** 2) + (i * (-61) + 971)):
        pass
    else:
        print(i)
        print("不对")
        break
    print("bingo")
#'''
      

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-12 17:29:04 | 显示全部楼层
python
-59231
Time:0.1665503978729248s
主要应用了b的取值为质数,a为大于-b的奇数
计算是否为奇数,提前计算了较大范围的质数集合,判断是否在其中是非常快的
  1. import time
  2. tt=time.time()
  3. def getzhishu(num):
  4.     l=list(range(1,num+1))
  5.     l[0]=0
  6.     s=set()
  7.     for i in range(num):
  8.         if not l[i]==0:
  9.             s.add(i+1)
  10.             n=2
  11.             while n*(i+1)<=num:
  12.                 l[n*(i+1)-1]=0
  13.                 n=n+1
  14.     return s
  15. s=getzhishu(79**2+1000*79+1000)
  16. best=(0,0)
  17. for b in getzhishu(1000):
  18.     for a in range(-b+2,1000,2):
  19.         # print((a,b))
  20.         for n in range(80):
  21.             if (n+a)*n+b not in s:
  22.                 best=max(best,(n-1,a*b))
  23.                 break

  24. print(best[1])
  25. print('Time:{}s'.format(time.time()-tt))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-10 18:29:52 | 显示全部楼层
-59231  0.036s
使用 primal 库,Miller-Rabin方法检测质数
  1. extern crate primal;
  2. use primal::*;

  3. fn f(a: i64, b: i64) -> usize {
  4.     for n in 0.. {
  5.         if (a + n) * n + b <= 1 || ((a + n) * n + b > 1 && !is_prime(((a + n) * n + b) as u64)) {
  6.             return n as usize;
  7.         }
  8.     }
  9.     0
  10. }

  11. fn main() {
  12.     let mut max_i = 0;
  13.     let mut max_j = 0;
  14.     let mut max_n = 0;
  15.     for i in -999..999 {
  16.         for j in -999..999 {
  17.             let n = f(i as i64, j as i64);
  18.             if n > max_n {
  19.                 max_i = i;
  20.                 max_j = j;
  21.                 max_n = n;
  22.             }
  23.         }
  24.     }
  25.     println!("b: {}\nc: {}\nn: {}\nans: {}", max_i, max_j, max_n, max_i * max_j);
  26. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 06:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表