比较裸的数位DP,需要注意的就是二分时一定要写成 mid=((long long)l+(long long)r)>>1;不然会溢出导致超时的,被这个坑了好一会儿。还有就是题目并没有说y一定大于x,所以需要判断一下。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>
#include <vector>
#include <cmath>
#include <stack>
using namespace std;
#define ll long long
#define int64 __int64
#define M 50005
#define N 1005
#define inf 1000010
#define mod 2520
int b , m;
int dig[105] , dp[105][350];
int Dfs(int index , int sum , int lim)
{
if (!index)return sum == m;
if (!lim && dp[index][sum] != -1)return dp[index][sum];
int i , up = lim ? dig[index] : b-1 , ret = 0;
for (i = 0 ; i <= up ; i++)
{
if (sum+i <= m)
ret += Dfs(index-1,sum+i,lim&&i==up);
}
if (!lim)dp[index][sum] = ret;
return ret;
}
int Solve(int k)
{
if (k < 0)return 0;
int len = 0;
while (k)
{
dig[++len] = k%b;
k /= b;
}
return Dfs(len , 0 , 1);
}
int main()
{
int tcase = 1;
int q , x , y , k;
while (~scanf("%d",&q))
{
printf("Case %d:\n",tcase++);
memset(dp , -1 , sizeof dp);
if (q == 1)
{
scanf("%d%d%d%d",&x,&y,&b,&m);
if (x > y)swap(x,y);
printf("%d\n",Solve(y)-Solve(x-1));
}
else
{
scanf("%d%d%d%d%d",&x,&y,&b,&m,&k);
if (x > y)swap(x,y);
int sumx = Solve(x-1);
int sumy = Solve(y);
int sum = sumy-sumx , ans;
if (sum < k)
printf("Could not find the Number!\n");
else
{
int l = x , r = y , mid;
while (l <= r)
{
mid=((long long)l+(long long)r)>>1;
int temp = Solve(mid);
if (temp-sumx >= k)
{
ans = mid;
r = mid-1;
}
else
l = mid+1;
}
printf("%d\n",ans);
}
}
}
return 0;
}