给定数字N,请找到可以从N的正整数倍获得的最小位数。
限制条件:1 <= N <= 10 ^ 5。
例子:
Input : N = 6
Output : 3
Explanation: 6*2 = 12, sum of digits is 1+2 = 3.
Input : N = 20
Output : 1
20*5 = 100, sum of digits is 1+0+0=1
方法:问题完全基于观察。对于N = 6,答案是12。
因此我们可以将12写成:1-(* 10)–> 10 –(+ 1)–> 11 –(+ 1)–> 12。序列描述的是我们可以写任何大于= 1的数字,即+1的和与* 10的乘积,从1开始。
另一个观察结果是,当我们在数字上加上+1时,数字的总和会增加+1,除非最后一位是9。
第二个观察结果是,当我们将数字乘以10时,数字总和保持恒定。
现在,由于我们想要N的倍数,所以N%N的任何倍数都将为0。
因此,通过以上分析,我们可以建立一个K个顶点的图,对于任何顶点X,从X到X + 1的节点权重将为1,从X到(X * 10)%N的节点权重将为为0。由于顶点位于0到N-1之内,所以取N为模。
答案将是从1到0的最短距离,因为(N的任何倍数)mod N = 0。
我们可以使用Dijkstra定理找到1和0之间的最短距离。将其设为d。答案将是1 + d,因为我们还必须考虑边0到1。
该解决方案的时间复杂度将为O(E + VLogV)= O(N + NLogN)= O(NlogN),因为我们最多将移动N个顶点和边。
还有一点要注意的是,因为在xyz..9之后,下一位数字将是abc..0,但这不会影响我们的答案。
证明:以N = 11为例,答案为2。从11 * 1 = 11到11 * 10 = 110。
由于110是N的10的倍数,也是一个答案,所以我们已经找到答案了,因为如果110是N的10的倍数,那么答案中必须存在一个小于此的数字且不带前导0,即11 。
因此,如果不是答案,我们将超过N的10的倍数,或者如果答案为N的10的倍数,我们将已经达到答案。
下面是上述方法的实现:
#include
using namespace std;
const int Maxx = 100005;
int N;
vector > Graph[Maxx];
/// Dijkartas algorithm to find the shortest distance
void Dijkartas(int source)
{
priority_queue, vector >,
greater > > PQ;
// Initialize all distances to be infinity
vector Distance(N + 2, 1e9);
// Push source in Priority Queue
PQ.push(make_pair(0, source));
int src = source;
Distance[src] = 0;
while (!PQ.empty()) {
int current = PQ.top().second;
PQ.pop();
for (auto& neighbours : Graph[current]) {
int v = neighbours.first;
int weight = neighbours.second;
if (Distance[v] > Distance[current] + weight) {
Distance[v] = Distance[current] + weight;
PQ.push(make_pair(Distance[v], v));
}
}
}
cout << "Minimum possible sum of digits is " <<
1 + Distance[0] << endl;
return;
}
// Function to calculate the minimum possible sum of digits
void minSumDigits(int N)
{
// Build a graph of N vertices with edge weight 1
for (int i = 1; i <= N; ++i) {
int From = (i) % N;
int To = (i + 1) % N;
int Wt = 1;
Graph[From].push_back(make_pair(To, Wt));
}
// In the same graph add weights 0 to 10's multiple of node X
for (int i = 1; i <= N; ++i) {
int From = (i) % N;
int To = (10 * i) % N;
int Wt = 0;
Graph[From].push_back(make_pair(To, Wt));
}
// Run dijartas to find the shortest distance from 1 to 0
Dijkartas(1);
return;
}
// Driver Code
int main()
{
N = 19;
minSumDigits(N);
return 0;
}
Minimum possible sum of digits is 2