思路:按数位dp的枚举思路,当遇到第一个满足的就直接return .注意边界条件就行。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e4+10;
char s[1005];
int n;
int mod;
int a[1005];
int dp[1005][1005][10];
int path[1005];
bool vis[1005];
int bit[1005];
void init()
{
bit[0]=1;
for(int i=1;i<=1001;i++)
{
bit[i]=bit[i-1]*10%mod;
}
}
bool dfs(int pos,int re,int m)
{
path[pos+1]=m;
if(pos==-1)
{
if(re%mod==0)
{
return true;
}
return false;
}
if(dp[pos][re][m]!=-1) return dp[pos][re][m];
bool ans=0;
if(vis[pos]==1)
{
ans=dfs(pos-1,(re+bit[pos]*a[pos])%mod,a[pos]);
if(ans)
{
dp[pos][re][m]=ans;
return 1;
}
}
else
{
int up=a[pos];
for(int i=0;i<=up;i++)
{
ans=dfs(pos-1,(re+bit[pos]*i)%mod,i);
if(ans)
{
dp[pos][re][m]=ans;
return true;
}
}
}
dp[pos][re][m]=ans;
return ans;
}
bool solve(int pos)
{
memset(dp,-1,sizeof(dp));
if(s[0]!='?')
{
int i=s[0]-'0';
return dfs(pos-1,i*bit[pos]%mod,i);
}
else
{
int i=1;
bool ans;
while(i<=9)
{
ans=dfs(pos-1,i*bit[pos]%mod,i);
if(ans)
{
return 1;
}
i++;
}
return 0;
}
}
int main()
{
scanf("%s",s);
scanf("%d",&n);
int len=strlen(s);
// if(len==1)
// {
// if(s[0]=='?')
// {
// printf("0\n");
// }
// return 0;
// }
for(int i=0;i<len;i++)
{
if(s[i]=='?')
{
a[len-i-1]=9;
}
else
{
a[len-i-1]=s[i]-'0';
vis[len-i-1]=1;
}
}
mod=n;
init();
bool ans=solve(len-1);
if(ans==0)
{
printf("*\n");
}
else
{
for(int i=len-1;i>=0;i--)
{
printf("%d",path[i]);
}
printf("\n");
}
return 0;
}
// ?294?? 17