版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38013346/article/details/82286506
Description
Input
Output
Solution
那么存在两种建边的方法
(相当于得到12)
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;
}