Problem B. Tidy Numbers
题意
定义 Tidy Numbers
是一个 10 进制非减数。如 8, 123, 555 和 224488 是 Tidy Numbers
,而 20, 321, 495 和 999990 不是。
问在 [1, N]
中最大的 Tidy Numbers
?
解法
迭代
对于 [1, x]
的最大 Tidy Number
,令截取 x 的前 k 位令为
xk
是Tidy Number
。若
xk
与 x 等长,则答案为
xk
。否则,即 x 的第 k+1 位小于第 k 位。尝试将
xk−1
, 若仍为 Tidy Number
,补上后面若干位均为 9 即为最大值。若不是 Tidy Number
,迭代寻找 [1, x_k-1]
中最大的 Tidy Number
,再补若干位 9 。
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<fstream>
using namespace std;
long long n, init[20] = {1ll};
bool check(long long x)
{
int pre = 9;
while(x)
{
if(x%10 > pre) return false;
pre = x % 10;
x /= 10;
}
return true;
}
long long solve(long long x)
{
int num[20], idx = -1;
while(x)
num[++idx] = x%10, x/=10;
long long ans = 0;
for(int i=idx;i;--i)
{
ans *= 10;
if(num[i] <= num[i-1])
ans += num[i];
else {
ans += num[i];
ans--;
if(!check(ans))
ans = solve(ans);
return ans = ans * init[i] + init[i]-1;
}
}
ans*=10;
ans += num[0];
return ans;
}
int main()
{
freopen("G:\\B.in", "r", stdin);
freopen("G:\\B.out", "w", stdout);
int T;
scanf("%d",&T);
for(int i=1;i<20;i++)
init[i] = init[i-1]*10;
for(int ica=1;ica<=T;ica++)
{
scanf("%I64d",&n);
printf("Case #%d: %I64d\n", ica, solve(n));
}
}