[ABC077D] Small Multiple

Description#

给定一个整数 K 。求一个 K 的正整数倍 S,使得 S 的数位累加和最小。

2K105

Solution#

先不去考虑 K 的倍数这件事。思考如何快速得到一些数的数位累加和。

一个数的数位和,可以看成这个数在当前数位上加了几次。那么如果我们从 1 出发,那么就会有两条路:当前数位加一或者进入到下一个数位,其体现为 +1×10。而 +1 会使数位和增加,但 ×10 不会。

但怎么找到 K 的倍数呢?我们从余数的角度来考虑。那么 +1×10 就相当于从一个余数连向另一个余数的边,+1 边权值为 1×10 边权值为 0。最终答案就为 10 的最短路。

Code#

#include<queue>
#include<cstdio>
#include<cstring>
#define N 100005
using namespace std;
int n,dis[N];
bool bj[N];
struct node {int x,dis;};
deque<node> q;
int main()
{
    scanf("%d",&n);
    memset(dis,0x3f3f3f3f,sizeof(dis));
    q.push_back((node){1,1});dis[1]=1;
    while (!q.empty())
    {
        int x=q.front().x,d=q.front().dis;q.pop_front();
        if (dis[x]<d) continue;
        if (bj[x]) continue;
        bj[x]=true;
        if (dis[(x+1)%n]>dis[x]+1)
        {
            dis[(x+1)%n]=dis[x]+1;
            if (!bj[(x+1)%n]) q.push_back((node){(x+1)%n,dis[(x+1)%n]});
        }
        if (dis[x*10%n]>dis[x])
        {
            dis[x*10%n]=dis[x];
            if (!bj[x*10%n]) q.push_front((node){x*10%n,dis[x*10%n]});
        }
    }
    printf("%d\n",dis[0]);
    return 0;
}
posted @   Thunder_S  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示
主题色彩