Small Multiple

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.
 

输入

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.

来源/分类

ABC077&ARC084 


题意:求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\n",spfa(k));
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/tian-luo/p/9415909.html