Small Multiple
时间限制: 1 Sec 内存限制: 512 MB题目描述
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.
Constraints
2≤K≤105
K is an integer.
输入
Input is given from Standard Input in the following format:
K
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的所有倍数中,各个数字和最小的那一个是多少。
考虑计算出这个倍数,假设这个数的最高位数字是x,那么我们要得到这个数,显然是在x后面加上它次高位的数字。
于是考虑建图。图中的点 i 就代表某一个数对k取余为 i 。当某个数z对k取余为 i 时,设dis[i]为此时这个数z的所有位的数字和(取余相同取数字和最小的)。显然答案就是dis[0]。
那么我们一开始假设答案的第一位为y,每次在y后面加一个数字i,得到y2,可以计算出y2%k的结果,就是(y*10+i)%k。而节点y到节点y2的边权就是 i。
然后开始时把1~9加入队列,因为答案的第一位可能是1~9,再跑spfa求dis[0]。
#include <bits/stdc++.h> #define N 100500 using namespace std; int vis[N]= {0}; int team[10*N],c1,c2; int dis[N]= {0}; int spfa(int x) { for(int i=0; i<=x; i++)dis[i]=INT_MAX; c1=c2=0; for(int i=1; i<=9; i++)team[c2++]=i,dis[i]=i,vis[i]=1; while(c1<c2) { int now=team[c1]; for(int i=0; i<=9; i++) { if(dis[(now*10+i)%x]>dis[now]+i) { dis[(now*10+i)%x]=dis[now]+i; if(!vis[(now*10+i)%x]) { team[c2++]=(now*10+i)%x; vis[(now*10+i)%x]=1; } } } vis[now]=0; c1++; } return dis[0]; } int main() { int k; scanf("%d",&k); printf("%d ",spfa(k)); return 0; }