#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)
#define bug printf("hihi\n")
#define eps 1e-8
typedef long long ll;
using namespace std;
#define INF 0x3f3f3f3f
#define N 100
int dp[12][N][N]; // 位置 和模k 数模k
int bit[N];
int k;
int dfs(int pos,int re,int rre,bool bound)
{
if(pos==-1) return re==0&&rre==0 ? 1:0;
if(!bound&&dp[pos][re][rre]>=0) return dp[pos][re][rre];
int up=bound ? bit[pos]:9;
int ans=0;
for(int i=0;i<=up;i++)
{
ans+=dfs(pos-1,(re*10+i)%k,(rre+i)%k,bound&&i==up);
}
if(!bound) dp[pos][re][rre]=ans;
return ans;
}
int solve(int n)
{
int len=0;
if(n==0) return 1;
while(n)
{
bit[len++]=n%10;
n/=10;
}
return dfs(len-1,0,0,true);
}
int main()
{
int i,j,t,ca=0;
int le,ri;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&le,&ri,&k);
if(k>=100)
{
printf("Case %d: 0\n",++ca);
continue;
}
memset(dp,-1,sizeof(dp));
printf("Case %d: %d\n",++ca,solve(ri)-solve(le-1));
}
return 0;
}
本文介绍了一种使用动态规划解决特定数值范围内两个数同时模K为0的问题的算法实现。通过递归深度优先搜索的方式,结合状态压缩,有效地计算出所有符合条件的数对个数。适用于K值较小的情况。
9682

被折叠的 条评论
为什么被折叠?



