| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2538 人关注过本帖
标题:在google treasure hunt 上看到的关于素数的问题,不是怎样找素数的问题!
只看楼主 加入收藏
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
回复 9楼 beyondyf
非常非常感谢版主的代码,我会花时间仔细看的,

比如输入19,21, 405, 就会产生19个,21个405个连续素数的和,

问题的要求是这些和应该相同,所以是不是要继续做判断,

直到找到和相同的那个最小的素数吧

The quieter you become, the more you can hear
2012-06-18 18:08
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
题目哪里提到要相同了?请仔细阅读题面。

重剑无锋,大巧不工
2012-06-18 18:43
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
下面是一个找素数的方法,用的是链表,把找到的素数串起来,

判断一个数是不是素数是就看他能不能被链表里的素数整除,

如果不能的话,那他就是素数了。这和版主杨大哥用的数组来存储的方法应该是一样的了

只是数组需要一开始就把大小定下来,链表确不用

因为任何一个合数都可以被若干个素数表示出来滴

下面是我看到的一个方法

程序代码:
typedef unsigned long long bignum;

struct primerec {
    bignum bn;
    struct primerec *next;
};

void findPrimes(bignum topCandidate) {

    printf("2\n");

    struct primerec *firstPrime = malloc(sizeof(struct primerec));

    assert(firstPrime != NULL);

    struct primerec *latestPrime = firstPrime;

    firstPrime->bn = 3;

    firstPrime->next = NULL;

    bignum candidate = 3;

    while(candidate <= topCandidate) {

        struct primerec *thisPrime = firstPrime;

        int prime = 1;

        while(thisPrime->bn * thisPrime->bn <= candidate) {

            if(candidate % thisPrime->bn == 0) {

                prime = 0;

                break;

            }

            thisPrime = thisPrime->next;

        }

        if(prime ) {

            printPrime(candidate);

            latestPrime->next = malloc(sizeof(struct primerec));

            assert(latestPrime->next != NULL);

            latestPrime = latestPrime->next;

            latestPrime->bn = candidate;

            latestPrime->next = NULL;

        }

        candidate += 2;

    }

    freeList(firstPrime);
}



我看了一下

$ time ./printPrime 10000000 > /dev/null

        3.92 real         3.91 user         0.00 sys

这个方法还算可以吧,

只是 ‘%’ 是个相当笨重的运算符, 所以如果能把它换掉就更好了

The quieter you become, the more you can hear
2012-06-18 18:58
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
回复 12楼 beyondyf
可是。。。可是。。

Find the smallest number that can be expressed as

    the sum of 19 consecutive prime numbers,

    the sum of 21 consecutive prime numbers,

    the sum of 405 consecutive prime numbers,

    the sum of 781 consecutive prime numbers,
这段话的意思应该是

找到最小的这样一个数,它可以被 19个,21个,405个,781个连续的素数表示出来


The quieter you become, the more you can hear
2012-06-18 19:02
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
哦?我的理解是找到满足如下要求的最小的质数,也就是说4个要求看作是4道题。

我想是我理解错了。为12楼的发言向你道歉。

你的代码并不完整,只是一部分,所以不好说对与错好与坏。

链表和数组存在着本质的不同。我之所以用数组是为了之后在查找时使用二分法以提高效率。而这一点用链表是实现不了的。链表的优点是插入删除操作方便,在检索上不行。

还有,我的代码完成的是存前一百万个素数,而你的代码看起来是存小于1千万的素数(你统计时间时用的参数)。

第1百万个素数是15485863,你试着把它作为输入参数看一下执行时间。

重剑无锋,大巧不工
2012-06-18 20:40
于祥
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:蒙面侠
威 望:5
帖 子:1047
专家分:4132
注 册:2011-4-24
收藏
得分:14 
顶贴

最基础的往往是你最容易忽略的!
2012-06-18 21:28
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:14 
修改了一下代码以求出题目要求的数。结果为9387361。是第626618个素数。也是一千五百万以内的唯一的结果。
程序代码:
#include<stdio.h>
#include<math.h>

#define    LENGTH_MAX    1000000

int prime[LENGTH_MAX] = {2, 3};

void init()
{
    int i, j, k, q;
    for(i = 2; i < LENGTH_MAX; prime[i++] = j)
    for(j = prime[i - 1] + 2;; j += 2)
    {
        for(q = sqrt(j), k = 1; prime[k] <= q && j % prime[k]; k++);
        if(prime[k] > q) break;
    }
}

int is_prime(int a)
{
    int from, to, p;
    for(from = 0, to = LENGTH_MAX - 1; from <= to;)
    {
        p = (from + to) >> 1;
        if(prime[p] > a) to = p - 1;
        else if(prime[p] < a) from = p + 1;
        else return 1;
    }
    return 0;
}

int find(int len, int * from)
{
    int i, j, s;
    if(*from + len > LENGTH_MAX) return 0;
    for(s = i = 0; i < len; s += prime[*from + i++]);
    for(i += *from; i < LENGTH_MAX && !is_prime(s); i++)
    {
        s += prime[i] - prime[i - len];
        if(s > prime[LENGTH_MAX - 1]) return 0;
    }
    if(i >= LENGTH_MAX) return 0;
    *from = i - len;
    return s;
}

void search(int plen, int * s, int * slen)
{
    int from, i, j, a;
    for(from = i = j = 0; (a = find(plen, &from)) && a <= s[*slen - 1]; from++)
    {
        while(i < *slen && s[i] < a) i++;
        if(s[i] == a) s[j++] = a;
    }
    *slen = j;
}

int main()
{
    int from, a;
    int s[1000], len;
    init();
    for(from = len = 0; a = find(781, &from); from++) s[len++] = a;
    search(405, s, &len);
    search(21, s, &len);
    search(19, s, &len);
    if(len >= 1) printf("%d\n", s[0]);
    return 0;
}


重剑无锋,大巧不工
2012-06-18 21:52
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
回复 17楼 beyondyf
好吧,70分归你!30分就留给咱们吧!非常非常感谢,我会花时间把版主的代码仔细推敲的!

The quieter you become, the more you can hear
2012-06-18 22:56
快速回复:在google treasure hunt 上看到的关于素数的问题,不是怎样找素数的问 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.027071 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved