Numbers
Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)
Submit Statistic Next Problem
Problem Description
Consider numbers from 1 to n.
You have to find the smallest lexicographically number among them which is divisible by k.
Input
Input file contains several test cases. Each test case consists of two integer numbers n and k on a line(1 ≤ n ≤ 1018, 1 ≤ k ≤ n).
The last test case is followed by a line that contains two zeroes. This line must not be processed.
Output
For each test case output one integer number — the smallest lexicographically number not exceeding n which is divisible by k.
Sample Input
2000 17
2000 20
2000 22
0 0
Sample Output
1003
100
1012
Hint
多组数据
Source
Andrew Stankevich Contest 22
Manager
mathlover
题意:
求一个小于N且能被k整除的字典序最小的数
对于每一个大于等于k位数的数组去构造被k整除字典序最小的情况
if(w[i]%k==0)a[++j]=w[i];
else a[++j]=w[i]+(k-w[i]%k);
这样保证了每一个位数为j的数,字典序是最小的,且能被k整除的,
最后在这些数里取一下最小字典序即可,
*那么只需要把每个数在尾部用0补成相同位数,然后比大小取min即可,输出再把尾巴的0去掉(直接记录位置就不需要去掉了)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
LL n,k,w[50],a[50];
int main()
{
w[1]=1;
for(int i=2;i<=20;i++) w[i]=w[i-1]*10;
while(~scanf("%lld%lld",&n,&k)&&(n+k))
{
int cnt;
for(cnt=1;w[cnt]<k;cnt++);
int j;
a[1]=k;
for(j=1;a[j]<=n&&a[j]>0;cnt++)
{
if(w[cnt]%k==0)a[++j]=w[cnt];
else a[++j]=w[cnt]+(k-w[cnt]%k);
}
LL ans=a[1],key=1;
for(int i=2;i<j;i++)
{
ans*=10;
if (ans>a[i]){ans=a[i];key=i;}
}
printf("%lld\n",a[key]);
}
return 0;
}