思路:
折半枚举+高精度技巧。
先dfs枚举出小于等于15位的情况。
dp[i]表示余数为i的最小的数。
_dp[i]表示余数为i正好15的数。
然后枚举余数i,把它乘以1e15再模n后得到t,然后找_dp[n-t]
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) const int N=1e6+5; const ll INF=0x3f3f3f3f3f3f3f3f; ll dp[N],_dp[N]; int n; void dfs(ll num,int deep){ if(num){ dp[num%n]=min(dp[num%n],num); if(deep==15){ _dp[num%n]=min(_dp[num%n],num); return ; } } dfs(num*10+1,deep+1); dfs(num*10+2,deep+1); } int main(){ ios::sync_with_stdio(false); cin.tie(0); cin>>n; mem(dp,INF); mem(_dp,INF); dfs(0,0); if(dp[0]!=INF){ cout<<dp[0]<<endl; return 0; } ll sum1=0,sum2=0; for(int i=0;i<n;i++){ if(dp[i]==INF)continue; ll t=i; for(int j=0;j<15;j++)t=(t*10)%n; ll x=n-t; if(_dp[x]==INF)continue; if(sum1==0||dp[i]<sum1){ sum1=dp[i]; sum2=_dp[x]; } } if(sum1)cout<<sum1<<sum2<<endl; else cout<<"Impossible"<<endl; return 0; }