简单易知存在ax+by=(a,b) 故ax'+by'=n,n必为(a,b)倍数
将%(a,b)的余数视为node,从u%(a,b)到0找最短路
dij优先队列维护花费,pre记录前导,num记录node对应的数字
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<cstring> #include<cmath> using namespace std; int a,b,n,u,v,p; int V[10],s[10],dis[100010],pre[100010],num[100010]; int gcd(int x,int y){ if(x%y==0) return y; return gcd(y,x%y); } struct node{ int u,v; bool operator<(const node &a)const{ return a.v<v; } }; priority_queue<node>q; void print(int x){ if(pre[x]==-1){ cout<<u; return; } print(pre[x]); cout<<num[x]; } int main(){ cin>>a>>b>>n; for(int i=1;i<=n;i++) cin>>s[i]; for(int i=1;i<=n;i++) cin>>V[s[i]]; cin>>u>>v; p=gcd(a,b); q.push({u,0}); pre[u]=-1; memset(dis,0x3f,sizeof(dis)); dis[u]=0; while(!q.empty()){ node u=q.top(); q.pop(); if((u.u*10+v)%p==0){ print(u.u); cout<<v; return 0; } for(int i=0;i<=9;i++) if(V[i]){ int v=(u.u*10+i)%p; if(dis[v]>dis[u.u]+V[i]){ dis[v]=dis[u.u]+V[i]; pre[v]=u.u; num[v]=i; q.push({v,dis[v]}); } } } cout<<-1; return 0; }