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); }