倍数

第2题     倍数 查看测评数据信息

对于一个正整数a来说,它的各位数字之和就是它的价值,例如a=133,那么a的价值=1+3+3=7。

你需要找到一个价值最小的正整数b, 且b是k的倍数, 输出满足条件的最小价值。

输入格式

 

一个整数k。2<=k<=100000。

 

输出格式

 

一个正整数。

 

输入/输出例子1

输入:

6

 

输出:

3

 

样例解释

 

12是6的倍数,且12的价值是3。

再也找不出价值小于3的正整数,使得该正整数是6的倍数。

 

1.涉及到整除的东西,不是除法就是模,要相结合

 

2.不是一定有图才是最短路,类似于改进,用优的改进劣的,都可以往这方面想想。

 

ljx/我

这题和图看着没关系,实则关系密切,刚开始一眼看肯定是暴力,但是必然会炸,于是就有了一些巧妙方法

余数(%k)作为dis[]数组的下标,然后它对应的价值就是

各位数字之和,例如k=6,那么初始化dis[0]=6。

接着,我们就在这个价值后面加入0~9这几个数,变成60,61,

62......然后再去模k,尝试改变dis[]的价值,取一个更优解,这就是一个“松弛”操作 啊!!!

例如刚开始 dis[2]=1e9(假设的,实际上并不是),然后6后面加2,发现变成62,余数2,价值8,8<dis[2],更新

#include <bits/stdc++.h>
using namespace std;

const int N=100005;
int k, dis[N], vis[N];
queue<int> q;
int main()
{
	scanf("%d", &k);
	memset(dis, 63, sizeof dis);
	for (int i=1; i<=k; i++) dis[i%k]=i, q.push(i%k);
	
	while (!q.empty())
	{
		int u=q.front();
		q.pop();
		vis[u]=0;
		
		for (int i=0; i<=9; i++)
		{
			int v=(u*10+i)%k;
			if (dis[v]>dis[u]+i)
			{
				dis[v]=dis[u]+i;
				if (!vis[v]) vis[v]=1, q.push(v);
			}
		}
	}
	
	printf("%d", dis[0]);
	return 0;
}

 

 

 

csh(搬)

我们希望的是这个最小值是不断改进出来的,这样就可以避免因为大范围寻找而浪费时间。改进让我们可以联想到最短路。但是怎么联系到最短路呢?b是k的倍数,就说明b%k==0,我们可以从余数开始思考。 拿这个样例来举例,它的余数就有1,2,3,4,5,0。一开始我们把这些余数所对应的正整数a设为1,2,3,4,5,6(这是符合情况下且最显而易见的)。接下来,利用价值b去改进,价值是所有数位加起来,10b和b的价值是一样的,不过是多了一个0;10b+1就比b的价值多了1;那么利用这个性质,从1开始(从小的价值开始改进,保证改变的会变小),用110+0,110+1,110+2........模k,让此时的价值对所对应余数原本的价值进行改进,改进完的就去改进别人。 例如,110+0=10,10%6=4,那么余数为4的数的价值就可以更新,这个的价值最小为1;1*10+1=11,11%6=5,那么余数为5的数的价值就可以更新,这个的价值最小为2.

前面说“一开始我们把这些余数所对应的正整数a设为1,2,3,4,5,6(这是符合情况下且最显而易见的)”,这里只设置1-9,因为其他的都可以通过*10+x得到。

#include<bits/stdc++.h>
using namespace std;
int k,mp[100000];
struct cmp{
    bool operator()(const int &p1,const int &p2)const{
        return p1>p2;   
    }
};
priority_queue<int,vector<int>,cmp>pq;
int main(){
    scanf("%d",&k);
    memset(mp,0x3f,sizeof(mp));
    for(int i=1;i<=min(k,9);i++)
        mp[i%k]=i;
    pq.push(1);
    while(!pq.empty())
    {   int x=pq.top();
        pq.pop();
        for(int i=0;i<=9;i++)
        {   int t=x*10+i;
            if(mp[t%k]>mp[x]+i)
            {
                mp[t%k]=mp[x]+i;
                pq.push(t%k);
            }
        }
    }
    cout<<mp[0];
    return 0;
}

 

posted @ 2024-02-01 07:54  cn是大帅哥886  阅读(10)  评论(0编辑  收藏  举报