首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

有关于最大公约数的一个有关问题

2012-10-13 
【求助】有关于最大公约数的一个问题!有一道题是求:一个整数N,找出所有小于它的正整数的个数,并且这个正整数

【求助】有关于最大公约数的一个问题!
有一道题是求:
  一个整数N,找出所有小于它的正整数的个数,并且这个正整数与它的最大公约数为1.

样例:
对于25608有7680个符合这个条件的正整数。 

我的思路:
从1开始,找出与它的最大公约数大于1的一个数,比如说2,然后将2,4,6,8……(2*n<N)记录下来,然后后面的这些就不用找了,最后知道所有的都找完。这个算法的时间太长了,勉强过了。希望哪位大神给出耗时很少的算法!

[解决办法]
按你的思路筛选法,x=1000000,耗时0.2s,我是x64的,x86的请将ulong64改成uint

C/C++ code
#include <stdio.h>#include <Windows.h>inline BOOLEAN IsEven(ULONG64 x){    if (x & 0x01ULL)        return FALSE;    else        return TRUE;}ULONG64 GCD(ULONG64 x, ULONG64 y){    if (x < y)        return GCD(y, x);    if (y == 0)        return x;    else    {        if (IsEven(x))        {            if (IsEven(y))                return GCD(x>>1, y>>1) << 1;            else                return GCD(x>>1, y);        }        else        {            if (IsEven(y))                return GCD(x, y>>1);            else                return GCD(y, x-y);        }    }}void TimeStart(LARGE_INTEGER *pBegintime){    QueryPerformanceCounter(pBegintime);}LPSTR TimeResult(LARGE_INTEGER *pBegintime, LPSTR szTime){    LARGE_INTEGER endtime;    LARGE_INTEGER freqtime;    LARGE_INTEGER resulttime;    QueryPerformanceCounter(&endtime);    QueryPerformanceFrequency(&freqtime);    resulttime.QuadPart = (endtime.QuadPart - pBegintime->QuadPart) * 1000 / freqtime.QuadPart;    sprintf(szTime, "%I64d小时%I64d分%I64d.%03I64d秒", resulttime.QuadPart / 3600000, (resulttime.QuadPart / 60000) % 60, (resulttime.QuadPart /1000) % 60, resulttime.QuadPart % 1000);    return szTime;}int main(){    const int x = 2560800;    int i = 0, count = 0, j = 0, n = 0;    unsigned char *tab = (unsigned char*)malloc(x);    memset(tab, 0x00, x);    LARGE_INTEGER b, f, e, r;    QueryPerformanceCounter(&b);    for (i=1; i<x; ++i)    {        if (tab[i])            continue;        if (GCD(x, i) == 1)            count++;        else        {            for (j=0, n=0; n<x; ++j)            {                n = i * j;                if (n<x)                    tab[n] = 1;            }        }    }    QueryPerformanceFrequency(&f);    QueryPerformanceCounter(&e);    r.QuadPart = (e.QuadPart - b.QuadPart) * 1000 / f.QuadPart;    printf("%d\n", count);    printf("%lld小时%lld分%lld.%03lld秒\n", r.QuadPart / 3600000, (r.QuadPart / 60000) % 60, (r.QuadPart /1000) % 60, r.QuadPart % 1000);    free(tab);    getchar();} 

热点排行