链接:
https://www.nowcoder.com/acm/contest/79/E
来源:牛客网
来源:牛客网
题目描述
小欧在上代数课的时候,老师向大家提出了一个问题,不定方程 ax+by=c 的整数解存在的充要条件是什么。
聪明的小欧立即举手给出了老师一个完美的回答,放学后,老师叫住小欧给了他一个思考题。
给出正整数 a 和 b 的值以及两个序列 S 和 V, 求出最小代价的正整数 c 使得不定方程 ax+by=c 有解,且 c 必须满足以下条件:
1. 组成 c 的数字必须是序列 S 内的。
2. 每使用序列 S 内的一个数字 S i 就会消耗掉代价 V i。
3. 序列 S 内的数字使用次数不限。
4. c 的首位为 u, c的末位为 v。(u,v 也是序列 S 内的)
如果有多个代价一样小的答案,只需要 c 的字典序最小的那一个。
聪明的小欧立即举手给出了老师一个完美的回答,放学后,老师叫住小欧给了他一个思考题。
给出正整数 a 和 b 的值以及两个序列 S 和 V, 求出最小代价的正整数 c 使得不定方程 ax+by=c 有解,且 c 必须满足以下条件:
1. 组成 c 的数字必须是序列 S 内的。
2. 每使用序列 S 内的一个数字 S i 就会消耗掉代价 V i。
3. 序列 S 内的数字使用次数不限。
4. c 的首位为 u, c的末位为 v。(u,v 也是序列 S 内的)
如果有多个代价一样小的答案,只需要 c 的字典序最小的那一个。
输入描述:
第一行三个个整数 a,b,n (1 <= a, b <= 100000, 2 <= n <= 10) 第二行 n 个整数 Si (0 <= Si <= 9) 第三行 n 个整数 Vi (1 <= Vi <= 1000) 最后一行两个整数 u,v(1 <= u <= 9, 0 <= v <= 9, u != v)
输出描述:
输出一行表示满足条件的 c 。 如果有多个输出字典序最小的。 如果不存在输出 -1 。
示例1
输入
10 15 2 2 0 1 1 2 0
输出
20
示例2
输入
17 17 4 0 1 2 7 1 1 1 1000 1 0
输出
1020
//分析:首先定义三个数组,数组是跟a,b相关的
//ax+by=c式子有解,则c%gcd(a,b)==0
//最重要的是优先队列思想
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 1000000
struct node
{
int s,v;
bool operator <(const node &a)const
{
return a.v<v;
}
};
int V[15],dis[100005],pre[100005],num[100005];
int p,v,u;
void print(int x)
{
if(pre[x]==-1)
{
cout<<u;
return ;
}
print(pre[x]);
cout<<num[x];
}
int bfs(int x)
{
memset(dis,INF,sizeof dis);
dis[x]=0;
pre[x]=-1;
priority_queue<node>que;
que.push({x,0});
while(!que.empty())
{
node tem=que.top();
que.pop();
if((tem.s*10+v)%p==0)
{
print(tem.s);
cout<<v<<endl;
return 1;
}
for(int i=0;i<10;i++)
if(V[i])
{
int ns=(tem.s*10+i)%p;
if(dis[ns]>dis[tem.s]+V[i])
{
dis[ns]=dis[tem.s]+V[i];
pre[ns]=tem.s;
num[ns]=i;
que.push({ns,dis[ns]});
}
}
}
return 0;
}
int main()
{
int a,b,n;
cin>>a>>b>>n;
p=__gcd(a,b);
int w[12];
for(int i=0;i<n;i++)
{
cin>>w[i];
}
for(int i=0;i<n;i++)
cin>>V[w[i]];
cin>>u>>v;
if(bfs(u%p)==0)cout<<-1<<endl;
}