[FROM WOJ]#3878 数字游戏

本文介绍了一个数字游戏的算法解决方案,游戏的目标是在指定的整数区间内找出所有各位数字之和模N为0的数。通过动态规划方法,预处理了一个三维数组来存储各种可能的数字组合,从而快速计算出结果。

#3878 数字游戏

题面
由于科协里最近真的很流行数字游戏,某人又命名了一种取模数,这种数字必须满足各位数字之和 mod N 为 0 。现在大家又要玩游戏了,指定一个整数闭区间 [a,b],问这个区间内有多少个取模数。
对于全部数据,1≤a,b≤231−1,1≤N&lt;1001≤a,b≤ 2^{31} − 1,1≤N&lt;1001a,b2311,1N<100

输入
题目有多组测试数据。每组只含三个数字 a,b,N

输出
对于每个测试数据输出一行,表示各位数字和 mod N 为 0 的数的个数。

样例输入
1 19 9

样例输出
2

SOL
f[i][j][k]f[i][j][k]f[i][j][k]表示iii位数最高位为jjj各位数之和为kkk的合法情况数,然后直接DP就行。

代码

#include<bits/stdc++.h>
using namespace std;
int a,b,n;
int f[15][10][110],h[15];
inline void pre(){
	for(int register i=0;i<10;i++)f[1][i][i]=1;
	for(int register i=2;i<=10;i++)
		for(int register k=0;k<10;k++)
			for(int register j=0;j<100;j++)
				for(int register t=0;t<10;t++)
					f[i][k][j+k]+=f[i-1][t][j];					
	
}
inline int solve(int x){
	int register len=0,ans=0,sum=0;
	while(x){
		h[++len]=x%10;
		x/=10;
	}
	for(int register i=len;i>0;i--){
		for(int register j=0;j<h[i];j++){
			int maxl=100/n;
			for(int register k=1;k<=maxl;k++)
				ans+=f[i][j][n*k-sum];
		}
		sum+=h[i];sum%=n;
		if(i==1&&sum%n==0)ans++;
	}
	return ans;
}
int main(){
	pre();
	while(scanf("%d%d%d",&a,&b,&n)!=EOF)printf("%d\n",solve(b)-solve(a-1));
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值