一分钟内算出21位数的水仙花数

本文介绍了一种使用大数运算实现的组合搜索算法,通过递归调用进行深度优先搜索,并利用自定义的大数类进行加、减、乘、比较等操作。同时,提出了一种优化策略来减少不必要的搜索分支,提高算法效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


#include<iostream>
#include <cstring>
#include <cstdio>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include<algorithm>
#define LL long long
#define M ((LL)100000000000000)
#define n (21)
using namespace std;

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 a2,a1;
    bigint(LL b2=0,LL b1=0){a2=b2;a1=b1;if(::len(b1)>14 || ::len(b2)>14) cout<<"err3"<<endl;}
    bigint operator+(bigint a)
    {
        LL c=(a.a1+a1)/M;
        LL aa1=(a.a1+a1)%M;
        LL aa2=a.a2+a2+c;
        return bigint(aa2,aa1);
    }
    bigint operator+(LL a)
    {
        return bigint(a2,a1)+bigint(a/M,a%M);
    }
    bigint operator-(bigint a)
    {
        LL c=0;
        if(a1<a.a1) c=1;
        if(a2<a.a2 || (a2==a.a2 && c)) cout<<"err1"<<endl;
        LL aa1=(M+a1-a.a1)%M;
        LL aa2=a2-a.a2-c;
        return bigint(aa2,aa1);
    }
    bigint operator*(LL a)
    {
        LL c=(a1*a)/M;
        LL aa1=(a1*a)%M;
        LL aa2=a2*a+c;
        return bigint(aa2,aa1);
    }
    bool operator<(bigint a)
    {
        if(a2<a.a2) return true;
        if(a2==a.a2 && a1<a.a1) return true;
        return false;
    }
    LL len()
    {
        LL ans=0;
        if(a2>0) return ::len(a2)+14;
        return ::len(a1);
    }
    void display()
    {
        if(a2==0)
        {
            cout<<a1<<endl;
            return;
        }
        cout<<a2;
        cout.fill('0');
        cout.width(14);
        cout<<a1<<endl;
    }
};

bigint mpow[10],mj[22];
LL a[30];

void mypow()
{
    mpow[0]=bigint();
    mpow[1]=bigint(0,1);
    LL i=2;
    for(;i<=9;i++)
    {
        mpow[i]=mpow[1];
        LL m=n;
        while(m--) mpow[i]=mpow[i]*i;
    }
}

bool judge(bigint b)
{
    if(b.len()!=n) return false;
    LL c[30],i=0,a1=b.a1,a2=b.a2;
    while(a1)
    {
        c[i++]=a1%10;
        a1/=10;
    }
    i=14;
    while(a2)
    {
        c[i++]=a2%10;
        a2/=10;
    }
    sort(c,c+n,cmp);
    for(i=0;i<n;i++) if(a[i]!=c[i]) {return false;}
    return true;
}

bool abcd=0;

void dfs(int x,int p,bigint t)
{
    if(abcd) return;
    if(t.len()>n) return;
    if(x>=n)
    {
        if(t.len()<n) abcd=1;
        if(judge(t)) t.display();
        return;
    }
    for(;p>=0;p--)
    {
        if(abcd) return;
        a[x]=p;
        dfs(x+1,p,t+mpow[p]);
    }
}

int main()
{
    mypow();
    dfs(0,9,bigint(0,0));
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值