解析:
因为n和p的范围都非常小,所以我们可以bfs求解。
对于每个数连接的时候,都把这个数放到左边。假设原始有一个数ai,长度leni
现在放入bi 那么连接起来就是 bi*10leni+ai.
设 f[x,10leni] 表示在当前模数p下的x。和下一个数要加进来乘上的长度10leni
每次都连接n个数,跑个Dijkstra ;
当x=0时,我们每次取最小
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+1000;
int len[N],pw[N],d[N];
int f[1005][1005];
int n,p;
string s;
struct node
{
int x,y,length;
bool operator > (const node &W) const {
return length>W.length;
}
};
int main()
{
scanf("%d %d",&n,&p);
pw[0]=1;
for(int i=1;i<=N;i++) pw[i]=(pw[i-1]*10)%p;
for(int i=1;i<=n;i++)
{
cin>>s;
len[i]=s.size();
for(int j=0;j<len[i];j++)
{
d[i]=(d[i]*10+(s[j]-'0'))%p;
}
}
memset(f,0x3f,sizeof f);
int ans=f[0][0];
f[0][1]=0;
priority_queue<node,vector<node> ,greater<node> >q;
q.push({0,1,0});
while(q.size())
{
auto t=q.top();
q.pop();
for(int i=1;i<=n;i++)
{
node tmp;
tmp.x=(t.x+d[i]*t.y)%p;
tmp.y=(t.y*pw[len[i]])%p;
tmp.length=(t.length+len[i]);
if(tmp.x==0) ans=min(ans,tmp.length);
if(f[tmp.x][tmp.y]>tmp.length)
{
f[tmp.x][tmp.y]=tmp.length;
q.push(tmp);
}
}
}
if(ans>=0x3f3f3f3f) ans=-1;
cout<<ans<<endl;
}