For every positive integer we may obtain a non-negative integer by multiplying its digits. This defines a functionf, e.g. f(38) = 24.
This function gets more interesting if we allow for other bases. In base 3, the number 80 is written as 2222, so:f3(80) = 16.
Picture by Mees de Vries
We want you to solve the reverse problem: given a base B and a number N, what is the smallest positive integer X such that fB(X) = N?
Input
The input consists of a single line containing two integers B and N, satisfying 2 < B ≤ 10000 and 0 < N < 263.
Output
Output the smallest positive integer solution X of the equatio
n fB(X) = N. If no such Xexists, output the word “impossible”. The input is carefully chosen such that X < 263holds (if X exists).
Sample Input 1
Sample Input 2
Sample Input 3
Sample Input 4
Sample Output 1
Sample Output 2
Sample Output 3
Sample Output 4
10 24 |
38 |
10 11 |
impossible |
9 216 |
546 |
10000 5810859769934419200 |
5989840988999909996 |
思路:先求出N的所有因子,接下来是个类似于完全背包的问题:对于这些价值和体积都为自身的因子组成总体积为N的最小值为多少。由于因子间是不连续的,要用到map实现 map传送门 设mp[i][j]表示还有i没被分解时所得到的最小价值为j
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
map<ll,ll>mp;
map<ll,ll>:: reverse_iterator it;
int prim[1008611],ans[1008611];
unsigned ll maxc=1ull<<63;
int main(){
ll n,b;
mp.clear();
scanf("%lld%lld",&b,&n);
if(n==1){
printf("1\n");
return 0;
}
ll k=0,tmp=n;
for(int i=2;i<b;i++){
if(n%i==0){
prim[k++]=i;
while(tmp%i==0){
tmp/=i;
}
}
}
if(tmp!=1){
printf("impossible\n");
return 0;
}
mp[n]=0;
for(it=mp.rbegin();it!=mp.rend();it++){//自后往前更新,保证u大的在前面
ll u=it->first;
ll v=it->second;
ll maxn=v%b;
for(ll i=k-1;i>=0;i--){
if(prim[i]<maxn)break;//由于是不降序列,遇到比上一位小的break
if(((long double)v*b+prim[i])>maxc)continue;
if(u%prim[i]!=0)continue;//防止爆long long
ll x=u/prim[i];
ll y=v*b+prim[i];
if(!mp[x]||mp[x]>y)mp[x]=y;
}
}
printf("%lld\n",mp[1]);
return 0;
}