题目描述
Find the smallest possible sum of the digits in the decimal notation of a positive multiple of K.
Constraints
2≤K≤105
K is an integer.
输入
Input is given from Standard Input in the following format:
K
输出
Print the smallest possible sum of the digits in the decimal notation of a positive multiple of K.
样例输入
6
样例输出
3
提示
12=6×2 yields the smallest sum.
题意:
给一个数 k,问在k的倍数中,求各个位数相加之和的最小的一个k的倍数。
当时刚看到这个题时想的是怎么才知道数的二倍是几位啊,出发点找错了。。。。。这个题目是让求各岗位数相加之和最小的,各个位数用整除
因为是k的倍数,对于数x,只需要取x属于[1,k]之间,在数后加0~9来构成一个新数y,保证y%k==0,即是各个位数取和的最小的k的倍数,为了保证不必要的位数加进来,导致结果不是最优,所以采用取模处理,所
以只需要看对k取模的余数即可,
在每一个数之间建立边权,每个节点代表该数对k取模的结果,两节点之间的边权代表各个位数和的差值
x —–x+1 各个位数的差值之和相差为1,所以边权为1;
x——x*10 各个位数的和加个0之后,其值不变,所以边权为0;
然后进行最短路,从取模为1,的节点,到取模为0 的节点的最短路的值,即为所求答案
最短路:板子题
#include<bits/stdc++.h>
//int k,a[100010];
using namespace std;
const int INF=0x3f3f3f3f;
const int N=1000010;
struct node{
int t, cost, next;
}e[N];
int head[N],cnt=0; //别忘了在主函数里初始化cnt=0,head=-1
void add(int u,int v,int cost)
{
//e[cnt]=node{v,cost,head[u]};
e[cnt].t=v;
e[cnt].cost=cost;
e[cnt].next=head[u];
head[u]=cnt++;
}
bool inq[N];
int dis[N],n;
void spfa(int s)
{
for(int i=0;i<=n;i++)dis[i]=INF;
memset(inq,0,sizeof(inq));
dis[s]=0;
queue<int>q;
q.push(s);//起点入队
while(!q.empty())
{
int u=q.front();q.pop();
inq[u]=0;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].t;
if(dis[v]>dis[u]+e[i].cost)
{
dis[v]=dis[u]+e[i].cost;
if(!inq[v]) //队列中有这个元素了,无需重复添加
{
inq[v]=1;
q.push(v);
}
}
}
}
}
int main(){
int i,j,k;
scanf("%d",&k);
memset(inq,0,sizeof(inq));
memset(head,-1,sizeof(head));
fill(dis,dis+N,INF);
//预处理
for(i=0;i<k;i++)
{
int x=i;
int xx=(i+1)%k;
int y=i*10%k;
add(x,xx,1);//建边
add(x,y,0);//建边
}
spfa(1);
printf("%d",dis[0]+1);//
return 0;
}