51nod1016

1016 水仙花数 V2

 
水仙花数是指一个 n 位数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身。(例如:1^3 + 5^3 + 3^3 = 153,1634 = 1^4 + 6^4 + 3^4 + 4^4)。
给出一个整数M,求 >= M的最小的水仙花数。
 

输入

一个整数M(10 <= M <= 10^60)

输出

输出>= M的最小的水仙花数,如果没有符合条件的水仙花数,则输出:No Solution

输入样例

300

输出样例

370

sol:好像标算是打表,感觉非常假,然后百度可知水仙花数一共只有89个,所以完全可行
贴上ak王xmy的打表代码以供参考
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=1e9;
struct NUM{//压位高精
    int t;ll a[10];
    friend NUM operator+(NUM x,NUM y){
        int i;
        for (i=0;i<x.t || i<y.t || x.a[i];i++){
            if (i+1>=x.t) x.a[i+1]=0;
            if (i<y.t) x.a[i]+=y.a[i];
            if (x.a[i]>=M) x.a[i+1]++,x.a[i]-=M;
        }
        x.t=i;
        return x;
    }
    friend NUM operator*(NUM x,int y){
        int i;
        for (i=0;i<x.t;i++) x.a[i]*=y;
        for (i=0;i<x.t || x.a[i];i++){
            if (i+1>=x.t) x.a[i+1]=0;
            x.a[i+1]+=x.a[i]/M,x.a[i]%=M;
        }
        x.t=i;
        return x;
    }
}f[11][61],s;//f[i][j]=i^j
int n,a[10],c[10],d[10],t1,t2,n1[50],n2[50];
void dfs(int x,int y,NUM s){
    t2=0;
    memset(c,0,sizeof(c));
    for (int i=0;i<s.t;i++){
        int t=s.a[i];
        for (int j=0;j<9;j++) c[n2[t2++]=t%10]++,t/=10;
    }
    while (t2 && !n2[t2-1]) t2--;
    if (t2>n) return;
    t1=0;
    NUM tmp=s+f[x][n]*(n-y);//最大能得到的数
    for (int i=0;i<tmp.t;i++){
        int t=tmp.a[i];
        for (int j=0;j<9;j++) n1[t1++]=t%10,t/=10;
    }
    while (t1 && !n1[t1-1]) t1--;
    if (t1<n) return;
    if (x && t1==t2){
        memset(d,0,sizeof(d));
        for (int i=n-1;~i;i--)
            if (n1[i]!=n2[i]) break;
            else d[n1[i]]++;
        for (int i=x+1;i<=9;i++)
            if (a[i]<d[i]) return;
    }
    if (!x){
        for (int i=1;i<=9;i++)
            if (a[i]!=c[i]) return;
        for (int i=t2-1;~i;i--) putchar(n2[i]|48);
        puts("");
        return;
    }
    for (int i=0;i<=n-y;i++){
        a[x]=i;
        dfs(x-1,y+i,s);
        s=s+f[x][n];
    }
}
int main(){
    puts("0");
    for (int i=1;i<10;i++){
        f[i][0].t=f[i][0].a[0]=1;
        for (int j=1;j<61;j++) f[i][j]=f[i][j-1]*i;
    }
    for (int i=1;i<=60;i++) n=i,dfs(9,0,s);
}
make


 
原文地址:https://www.cnblogs.com/gaojunonly1/p/10720810.html