题目
夹克爷的远古帖上有打表的方法,但两份代码一个C#,一个java,懒得看
水仙花数的个数是有限的,位数最多39位,不知道怎么证,反正跑出来的结果是这样的
我是自己打的表,本机大概运行13s可跑出来
具体方法就是:枚举水仙花数中
1
−
9
1-9
1−9的个数,剩下的位填
0
0
0,这样就能计算出水仙花数,判断
1
−
9
1-9
1−9的个数是否与枚举的一样即可
从
9
9
9到
1
1
1枚举可以优化
我有三个剪枝(假设当前每个数
n
n
n次方的和为
s
s
s,当前填到
x
x
x):
1.
1.
1.如果
s
s
s的位数已经
>
n
>n
>n,那么
r
e
t
u
r
n
return
return
2.
2.
2.如果剩下的数全填最大的还不到
n
n
n为,那么
r
e
t
u
r
n
return
return
3.
3.
3.如果剩下的数全填最大的前几位与
s
s
s对应位相同,那么这几位一定不会变了,而每个数的个数是从大到小枚举的,所以那些大于
x
x
x的数的个数不会增加,但如果前几位中有大于
x
x
x的数的个数大于枚举出这个数字应该出现个数,那么
r
e
t
u
r
n
return
return,具体见代码
#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][42],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<42;j++) f[i][j]=f[i][j-1]*i;
}
for (int i=1;i<=39;i++) n=i,dfs(9,0,s);
}
这是交上去的代码:
#include<bits/stdc++.h>
using namespace std;
string s,t[]={"153","370","371","407","1634","8208","9474","54748","92727","93084","548834","1741725","4210818","9800817","9926315","24678050","24678051","88593477","146511208","472335975","534494836","912985153","4679307774","32164049650","32164049651","40028394225","42678290603","44708635679","49388550606","82693916578","94204591914","28116440335967","4338281769391370","4338281769391371","21897142587612075","35641594208964132","35875699062250035","1517841543307505039","3289582984443187032","4498128791164624869","4929273885928088826","63105425988599693916","128468643043731391252","449177399146038697307","21887696841122916288858","27879694893054074471405","27907865009977052567814","28361281321319229463398","35452590104031691935943","174088005938065293023722","188451485447897896036875","239313664430041569350093","1550475334214501539088894","1553242162893771850669378","3706907995955475988644380","3706907995955475988644381","4422095118095899619457938","121204998563613372405438066","121270696006801314328439376","128851796696487777842012787","174650464499531377631639254","177265453171792792366489765","14607640612971980372614873089","19008174136254279995012734740","19008174136254279995012734741","23866716435523975980390369295","1145037275765491025924292050346","1927890457142960697580636236639","2309092682616190307509695338915","17333509997782249308725103962772","186709961001538790100634132976990","186709961001538790100634132976991","1122763285329372541592822900204593","12639369517103790328947807201478392","12679937780272278566303885594196922","1219167219625434121569735803609966019","12815792078366059955099770545296129367","115132219018763992565095597973971522400","115132219018763992565095597973971522401"};
int i;int main(){for(cin>>s;i<79;i++)if (t[i].size()==s.size()?t[i]>s:t[i].size()>s.size()) return cout<<t[i],0;puts("No Solution");}