思路:因为19位情况太多,要暴力枚举每位肯定会TE,所以为了优化时间复杂度,可以枚举n位数字中
每个数字出现的次数,记录下来,每次枚举到n位就判断所求的和是否满足枚举的情况。
我先存起来每个数字的n次方,方便直接使用。
Code:
#include <bits/stdc++.h>
#define LL unsigned long long
using namespace std;
const int AX = 1e2+6;
int vis[10];
map<LL,int>mp;
LL quick( LL a , LL b ){
LL ans = 1;
while( b ){
if( b & 1 ){
ans *= a;
}
b >>= 1;
a *= a;
}
return ans ;
}
LL sum ;
LL b[AX];
LL res[AX];
int n;
int cnt;
void dfs( int v , int num ){
if( v > 9 ) return;
if( num > n ) return ;
if( num == n ){
if( sum <= 0 ) return;
LL t = sum;
int c[10] = {0};
while( t ){
int tmp = t % 10;
t /= 10;
c[tmp] ++;
}
for( int i = 0 ; i <= 9 ; i++ ){
if( c[i] != vis[i] ) return;
}
if( !mp[sum] ){
res[cnt++] = sum;
mp[sum] = 1;
}
}
for( int i = 0 ; i <= 8 ; i++ ){
if( v < 9 ){
vis[v+1] += i ;
sum += i * b[v+1];
dfs( v + 1 , num + i );
vis[v+1] -= i ;
sum -= i * b[v+1];
}
}
}
int main(){
cnt = 0;
scanf("%d",&n);
for( int i = 1 ; i <= 9 ; i++ ){
b[i] = quick( i , n );
}
for( int i = 0 ; i <= 3 ; i++ ){
sum = 0;
memset( vis , 0 , sizeof(vis) );
vis[0] += i;
dfs( 0 , i );
vis[0] -= i;
}
if( !cnt ) printf("-1\n");
else{
sort( res , res + cnt );
for( int i = 0 ; i < cnt ; i++ ){
cout << res[i] << ' ';
}printf("\n");
}
return 0;
}