1. 程式人生 > >21位水仙花,C++大整數類

21位水仙花,C++大整數類

首先宣告,接觸這個問題時候,大整數類,我還不大知道,所以,找了網上的原始碼看了一下思路,自己敲了一遍,給後來人參考。

執行時間51s,

#include <iostream>
#include <algorithm>
#include <time.h>
using namespace std;
#define  LL   long long
#define  base (LL)100000000000000
#define  N    21
bool cmp(LL a,LL b)
{
    return a>b;
}
LL len(LL x)
{
    LL i=0;
    while(x) i++,x/=10;
    return i;
}
struct bigint
{
    LL high_p,low_p;
    bigint(LL h_p=0,LL l_p=0)//建構函式
    {
        high_p=h_p;
        low_p=l_p;
    }
    //過載bigint類加
    bigint operator +(bigint add)
    {
        LL s1=(add.low_p+low_p)/base;//求出溢位
        LL temp1=(add.low_p+low_p)%base;//低位
        LL temp2=high_p+add.high_p+s1;//高位
        return (bigint(temp2,temp1));
    }
    //過載bigint 與LL加
    bigint operator +(LL add)
    {
        return (bigint(high_p,low_p)+bigint(add/base,add%base));//long long轉化為大整數類
    }
    //過載bigint與LL相乘
    bigint operator *(LL mul)
    {
        LL s1=(low_p*mul)/base;
        LL temp1=(low_p*mul)%base;
        LL temp2=high_p*mul+s1;//有一定危險
        return bigint(temp2,temp1);
    }
    LL big_len()
    {
        if(high_p>0)return len(high_p)+14;
        else{
            return len(low_p);
        }
    }
};
bigint mul_table[10];//定義21次方表
LL index[21];
//建立21次方表
void creatTable()
{
    mul_table[0]=0;
    mul_table[1]=bigint(0,1);
    int num;
    LL i=2;
    for(;i<10;i++)
    {
        num=N;
        mul_table[i]=bigint(0,1);//初始化
        while(num--)mul_table[i]=mul_table[i]*i;
    }
}
//判斷是否滿足條件
//主要判斷順序是否滿足
bool judge(bigint sum)
{
    if(sum.big_len()!=N)return false;
    LL container[25];
    LL temp1=sum.high_p,temp2=sum.low_p;
    int i=0;
    while(temp2)
    {
        container[i++]=temp2%10;
        temp2=temp2/10;
    }
    i=14;
    while(temp1)
    {
        container[i++]=temp1%10;
        temp1=temp1/10;
    }
    sort(container,container+N,cmp);
    for(i=0;i<N;i++)
    {
        if(index[i]!=container[i])return false;
    }
    return true;
}
void display(bigint sum)
{
    cout<<sum.high_p<<sum.low_p<<endl;
}
//遞迴安排21位數順序
void daffDFS(int x,int data,bigint sum)
{
    if(sum.big_len()>N)return;
    if(x>=N)//安排完
    {

        if(sum.big_len()<N)return;//不符合
        if(judge(sum))display(sum);
    }else
    {
        for(;data>=0;data--)//傳入9
        {
            index[x]=data;//按照從大到小順序排好,這樣省了很多事情
            daffDFS(x+1,data,sum+mul_table[data]);
        }
    }


}
int main()
{
    clock_t start=clock();
    creatTable();
    daffDFS(0,9,bigint(0,0));
    clock_t myend=clock();
    float mytime=(myend-start)/CLOCKS_PER_SEC;

    cout<<mytime<<"S"<<endl;
    return 0;
}