回 帖 发 新 帖 刷新版面

主题:第36次编程比赛第1题题目

法雷序列:
对任意给定的一个自然数n,将分母小于等于n的不可约的真分数按升序排列,
并且在第一个分数之前加上数0/1,在最后一个分数之后加上1/1,这个序列
称为n级法雷序列,以Fn表示。例如,F8为:
0/1, 1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 
5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8, 1/1。

请编程输出任意的Fn序列。

函数原型:
// n - 序列级数
// farey[] - 存放Fn序列,以','分隔
void FareySequence(int n, char farey[]);

例:
输入:
5

数组中存放结果为:
0/1,1/5,1/4,1/3,2/5,1/2,3/5,2/3,3/4,4/5,1/1

回复列表 (共32个回复)

31 楼

//第三部分
//将分母为n的最简分数,添加到数组pFareyArray中去
BOOL AddToFractionArray(int n,FareyArray *pFareyArray,
    PrimeTab *pPrimeTab,
    DivArea *pDivAreaTab,
    int nDiv,
    int maxIdx)
{
    BOOL bIsPrime;
    int j,j1,j2,k;
    Fraction  frac;
    DWORD t;
    bIsPrime=Farey_isPrime(n,pFareyArray,pPrimeTab);
    if ( bIsPrime)
    {
        for (j=1;j<n;j++)
        {
            frac.numerator=j;
            frac.denominator=n;
            k=j*nDiv/n;
            g_fareyArray.array.Data[pDivAreaTab[k].pt]=frac;
            pDivAreaTab[k].pt++;
        }
    }
    else
    {
        memset( g_fareyArray.pByteArray,0,g_fareyArray.byteArrayLen);
        //筛去和分母不互质的所有分子
        for (j1=0;j1<g_fareyArray.fac_count;j1++)
        {
            t=g_fareyArray.fac[j1];
            for (j2=t;j2<n;j2+=t)
                g_fareyArray.pByteArray[j2]=1;
        }
        
        for (j1=1;j1<n;j1++)
        {
            //仅仅将和n(分母)互质的数组成的分数添加到分数数组
            if (g_fareyArray.pByteArray[j1]==0)
            {
                frac.numerator=j1;
                frac.denominator=n;
                k=j1* nDiv /n;
                g_fareyArray.array.Data[pDivAreaTab[k].pt]=frac;
                pDivAreaTab[k].pt++;

            }
        }

    }
    return TRUE;
}

int SataticDistributeFarey(int n,
    FareyArray *pFarey,
    PrimeTab *pTab,
    DivArea *pDivTab,
    int nDiv)
{
    int i,j1,j2,s,k,count;
    BOOL bIsPrime;
    double t;
    //-------------------------    
    memset(pDivTab,0,sizeof(DivArea)*nDiv);

    count=0;
    //t=currTime();
    for (i=2;i<=n;i++)
    {
        bIsPrime=Farey_isPrime(i,pFarey,pTab);
        if ( bIsPrime)
        {
            count+=(i-1);
            for (j1=1;j1<i;j1++)
            {
                k=(j1 * nDiv/ i);
                pDivTab[k].count++;
            }
        }
        else
        {
            memset( g_fareyArray.pByteArray,0,g_fareyArray.byteArrayLen);
            for (j1=0;j1<g_fareyArray.fac_count;j1++)
            {
                s=g_fareyArray.fac[j1];
                for (j2=s;j2<i;j2+=s)
                    g_fareyArray.pByteArray[j2]=1;
            }
        
            for (j1=1;j1<i;j1++)
            {
                if (g_fareyArray.pByteArray[j1]==0)
                {
                        k=(j1 * nDiv/ i);
                        pDivTab[k].count++;
                    count++;
                }
            }
    
        }
    }
    
    for (i=1;i<nDiv;i++)
    {
        pDivTab[i].base=pDivTab[i-1].base+ pDivTab[i-1].count;
        pDivTab[i].pt=pDivTab[i].base;
    
    }
    
    //t=currTime()-t;
    #ifdef OUT_TIME
    printf("stat time=%.12f s\n",t);
    printf("count=%d scale=%.8f\n",count,(double)count/(double)n/(double)n);
    
    #endif
    return count;
}

32 楼

//第四部分
void FareySequence(int n,char farey[])
{
    int i,nDiv,total;
    double t1,t2,t3;
    BOOL bRet;
    DivArea *pDivAreaTab=NULL;
    //----------------------------------
    
    farey[0]=0;
    
    total= n * n * 3/10;
    if (total<=1024)
        nDiv=1;
    else
    {
        double e =(int)( log((double)total)/log(2.00));
        nDiv= (1 << (int)(e/2));
    }

    bRet=PrimeTab_ReSift(&g_primeTab,n);
    if (!bRet)
        return;
    
    if (!Farey_Init(&g_fareyArray,n))
        return ;

    pDivAreaTab=new DivArea[nDiv];
    if (pDivAreaTab==NULL)
        return;
    
    total=SataticDistributeFarey(n,&g_fareyArray,&g_primeTab,pDivAreaTab,nDiv);
    FractionArray_setSize(&(g_fareyArray.array),total);

    #ifdef OUT_TIME
    t1=currTime();
    #endif
    for (i=2;i<=n;i++)
    {
        //printf("i=%d\n",i);
        bRet=AddToFractionArray(i,&g_fareyArray,&g_primeTab,pDivAreaTab,nDiv,total);
        if (!bRet)
            return;
    }
    g_fareyArray.array.count=g_fareyArray.array.size;
    #ifdef OUT_TIME
    t1=currTime()-t1;
    #endif
    

    #ifdef OUT_TIME
    t2=currTime();
    #endif
    FractionArray_Sort(&(g_fareyArray.array),pDivAreaTab,nDiv);
    
    #ifdef OUT_TIME
    t2=currTime()-t2;
    t3=currTime();
    #endif

    FractionArray_output(&(g_fareyArray),farey);
    #ifdef OUT_TIME
    t3=currTime()-t3;
    #endif

    FractionArray_Free(&(g_fareyArray.array));
    
    #ifdef OUT_TIME
    printf("calc time=%.12f s\nSort time=%.12f s\noutput time=%.12f s\n",t1,t2,t3);
    #endif
}



int main(int argc, char* argv[])
{
    
    int n;
    char *pBuff=NULL;
    char name[32]; 
    FILE *fp=NULL;

    InitData();

    while (1)
    {
        printf("n=?");
        scanf("%d",&n);
        if (n==0)
            break;
        pBuff=new char[n*n*4+4096];
        if (pBuff==NULL)
            return 0;
        FareySequence(n,pBuff);
        sprintf(name,"%d.txt",n);
        
        fp=fopen(name,"wt");
        fwrite(pBuff,1,strlen(pBuff),fp);
        fclose(fp);    
        delete[] pBuff;
    }

    FreeData();
    return 0;
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册