4612: [Wf2016]Forever Young
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 211 Solved: 56
[ Submit][ Status][ Discuss]
Description
将一个数y转化成b进制数,使得他>=l,且<y,且转化后均为0~9,使b最大。
Input
一行两个数y(10<=y<=10^18)和l(10<=l<=y)。
Output
输出最大的合法的b。
Sample Input
1000000000000000000 10
Sample Output
1000000000000000000
这题题意有点难懂啊(而且题面貌似有点问题,应该是“且<=y”)
大概意思是给你两个十进制数x和y,你要将x转化成一个b进制数k,要求①k每一位只能包含数字0到9;
②在假设x和y已经是b进制下的情况下有x>=k>=y,求满足条件最大的b
很显然x>=k只需要b>=10就一定满足,问题就是如何满足k>=y和条件①了
分情况讨论:
假设答案b>1000000,那么k一定是小于1000的,这个时候暴力枚举k就好了
然后对于每个k二分b的值,如果满足b进制下的k转化成10进制正好等于x,那么说明这个b可行
(注意防止爆long long)
假设答案b<=1000000,直接暴力b,然后判断转成的k是否满足>=y以及条件①即可
#include<stdio.h>
#include<algorithm>
using namespace std;
#define LL long long
LL Jud(LL x, LL k)
{
LL now, temp;
now = 0, temp = 1;
while(x)
{
if(x%k>=10)
return -1;
now += temp*(x%k);
x /= k;
temp *= 10;
}
return now;
}
LL Check(LL x, LL k)
{
return x%10+(x/10%10)*k+(x/100)*k*k;
}
int main(void)
{
LL n, m, i, ans, l, r, mid;
while(scanf("%lld%lld", &n, &m)!=EOF)
{
ans = 10;
for(i=m;i<=999;i++)
{
l = 1, r = (LL)1e18;
if(i>=100)
r = 1e9;
while(l<r)
{
mid = (l+r)/2;
if(Check(i, mid)>=n)
r = mid;
else
l = mid+1;
}
if(Check(i, r)==n)
ans = max(ans, r);
}
for(i=1000000;i>=ans;i--)
{
if(Jud(n, i)>=m)
{
ans = i;
break;
}
}
printf("%lld\n", ans);
}
return 0;
}