您的位置:首页 > 其它

arc084_b (思维+最短路)(好题)

2017-11-07 20:07 302 查看

题目

传送门

D - Small Multiple

Time limit : 2sec / Memory limit : 256MB

Problem Statement

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

Input is given from Standard Input in the following format:

K

Output

Print the smallest possible sum of the digits in the decimal notation of a positive multiple of K.

Samples

InputOutputStatement
6312=6×2 yields the smallest sum
41511111=41×271 yields the smallest sum
7999236

分析

题意就是给一个数 k ,问他的正整数倍数中,(十进制下)每一位的和最小是多少。

这题也是一道通过建图求最短路的思维好题。

新建一个图,共 k 个节点,代表 模k 得到的值。

可以先建好一个图,建边的依据是已知一个数
x%k=p
,那么在 x 后面再加一位数得到 y ,可以明确地知道
y%k
的值,于是就得到了一个图,每条边代表往后加一位,边权就是这一位的数字。

跑一边最短路,其中 dis[i] 意义就是模 k 余 i 的数中每一位的和最少是多少,开始
1~9
都加入队列(它们为第一位都可以),跑一次 SPFA ,最后输出 dis[0] 即可。

程序

#include <cstdio>
#include <cstring>
#define For(x) for(int h=head[x],o=V[h],w=W[h]; h; o=V[h=to[h]],w=W[h])
using namespace std;
int head[100005],to[1000005],V[1000005],W[1000005],num;
int q[10000005],l,r,f[100005],dis[100005];
int k;
void Add(int x,int y,int z){
to[++num]=head[x],head[x]=num,V[num]=y,W[num]=z;
}

void SPFA(){
memset(dis,0x7f,sizeof(dis));
for (int i=1; i<10; i++) q[++r]=dis[i]=f[i]=i;      //起始位(及最终数的最高位)是 1~9 都可以,都要加入队列中
for (l=1; l<=r; l++){
For(q[l]) if (dis[o]>dis[q[l]]+w){
dis[o]=dis[q[l]]+w;

a740
if (!f[o]){
f[o]=1;
q[++r]=o;
}
}
f[q[l]]=0;
}
}

void debug(){
for (int i=0; i<k; i++){
printf("%d\t",i);
For(i) printf("(%d %d) ",o,w);
puts("");
}
puts("");
}

int main(){
scanf("%d",&k);
for (int i=1; i<k; i++)
for (int j=0; j<10; j++)
Add(i,(i*10+j)%k,j);        //每个模数往后加一个位(0~9都可),可以形成一个到另一个模数的边
SPFA();
printf("%d",dis[0]);                //通过重重操作,最后得到模数为 0 (k的正整数倍)的路径长就是每一位的和
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: