Description
题 意 就 是 给 一 个 数 k , 问 他 的 正 整 数 倍 数 中 , ( 十 进 制 下 ) 每 一 位 的 和 最 小 是 多 少 。 题意就是给一个数 k ,问他的正整数倍数中,(十进制下)每一位的和最小是多少。 题意就是给一个数k,问他的正整数倍数中,(十进制下)每一位的和最小是多少。
Input
2 ≤ k ≤ 1 0 5 2\leq k\leq 10^5 2≤k≤105
Output
k 的 倍 数 最 小 的 每 一 位 位 数 和 。 k的倍数最小的每一位位数和。 k的倍数最小的每一位位数和。
Solution
这
题
也
是
一
道
通
过
建
图
求
最
短
路
的
思
维
好
题
。
这题也是一道通过建图求最短路的思维好题。
这题也是一道通过建图求最短路的思维好题。
新
建
一
个
图
,
共
k
个
节
点
,
代
表
模
k
得
到
的
值
。
新建一个图,共 k 个节点,代表 模k 得到的值。
新建一个图,共k个节点,代表模k得到的值。
可
以
先
建
好
一
个
图
,
建
边
的
依
据
是
已
知
一
个
数
x
%
k
=
p
。
可以先建好一个图,建边的依据是已知一个数x\%k=p。
可以先建好一个图,建边的依据是已知一个数x%k=p。
那么存在两种建边的方法
1.
x
→
(
x
+
1
)
%
k
代
价
是
1
1.x \to (x+1)\%k \ \ \ \ \ \ 代价是1
1.x→(x+1)%k 代价是1
2.
x
→
(
x
∗
10
)
%
k
代
价
是
0
2.x \to (x*10) \% k \ \ \ \ \ 代价是0
2.x→(x∗10)%k 代价是0
于
是
答
案
就
是
从
最
小
的
正
数
1
到
达
0
的
最
短
路
径
。
于是答案就是从最小的正数1到达0的最短路径。
于是答案就是从最小的正数1到达0的最短路径。
k
=
6
时
k = 6 时
k=6时
f
i
r
s
t
:
1
→
2
→
3
→
0
(
相
当
于
得
到
30
)
first : 1 \to 2 \to 3 \to 0 (相当于得到30)
first:1→2→3→0(相当于得到30)
s
e
c
o
n
d
:
1
→
4
→
5
→
0
second : 1 \to 4 \to 5 \to 0
second:1→4→5→0 (相当于得到12)
最
短
路
是
3
最短路是3
最短路是3
Codes
/* 很神奇的一道题目
* 求出k的倍数的正数x,使得x的位数和最小。
* eg k = 6 x = 12(位数和为3) x = 30(位数和为3)
*
* 考虑正数x 其变为 x+1 需要代价1.
* 正数x 变成 x*10 需要代价0.
* 由于我们只需要得到k的倍数,也就是说在 %k 意义下为0的点。
* 所以只有[0,k-1]k点。对每个点建立两条边,分别为(x+1)%k 和 (x*10)%k
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
const int inf = 0x3f3f3f3f;
struct Edge {
int to,val;
Edge(){}
Edge(int _t,int _v){to = _t;val = _v;}
};
struct qNode {
int u,val;
qNode(){}
qNode(int _u,int _v) {u = _u;val = _v;}
bool operator < (const qNode &a) const{
return val > a.val;
}
};
vector<Edge> ways[maxn];
int dist[maxn];
bool vis[maxn];
int n;
inline void init() {
for(int i=0;i<maxn;i++) ways[i].clear();
memset(vis,0,sizeof(vis));
memset(dist,inf,sizeof(dist));
}
inline void addedge(int from,int to,int val) {
ways[from].push_back(Edge(to,val));
}
int solve(int from,int to) {
priority_queue<qNode> qu;
dist[from] = 1;
qu.push(qNode(from,1));
qNode now;
while(!qu.empty()) {
now = qu.top();qu.pop();
int u = now.u;
if(vis[u]) continue;
vis[u] = true;
for(auto tmp:ways[u]) {
int v = tmp.to,cost = tmp.val;
if(!vis[v] && dist[v] > dist[u]+cost) {
dist[v] = dist[u] + cost;
qu.push(qNode(v,dist[v]));
}
}
}
return dist[to];
}
int main()
{
while(~scanf("%d",&n)){
init();
for(int i=1;i<n;i++) {
addedge(i,(i+1)%n,1);
addedge(i,(i*10)%n,0);
}
int ans = solve(1,0);
printf("%d\n",ans);
}
return 0;
}