X mod f(x)

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2792    Accepted Submission(s): 1101

Problem Description
Here is a function f(x):
   int f ( int x ) {
    if ( x == 0 ) return 0;
    return f ( x / 10 ) + x % 10;
   }

   Now, you want to know, in a given interval [A, B] (1 <= A <= B <= 109), how many integer x that mod f(x) equal to 0.

 
Input
   The first line has an integer T (1 <= T <= 50), indicate the number of test cases.
   Each test case has two integers A, B.
 
Output
   For each test case, output only one line containing the case number and an integer indicated the number of x.
 
Sample Input
2
1 10
11 20
 
Sample Output
Case 1: 10
Case 2: 3
 
Author
WHU
 
Source
 
/*题意:计算区间内一个数字各位之和能整除该数字的个数
思路:分别计算出[1, b]中符合条件的个数和[1, a-1]中符合条件的个数。
d[l][i][j][k]表示前l位和为i模j的结果为k的数的个数,那么就有方程
d[l+1][i+x][j][(k*10+x)%j] += d[l][i][j][k]
预处理出d[l][i][j][k],然后再逐位统计即可。*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std; int bit[];
int dp[][][][];
//d[l][i][j][k]表示前l位和为i模j的结果为k的数的个数
void set()//打表预处理出来你需要的数据
{
int i,j,k,l,x;
for(i = ; i<=; i++)
dp[][][i][] = ;
for(l = ; l<; l++)//枚举的是前l位
for(i = ; i<=l*; i++)//枚举的是当前和,最大和是l*9
for(j = ; j<=; j++)//不可能比81还大,总共才九位数,总和最大就是81,j>81的话得到的就是自己了
for(k = ; k<j; k++)
for(x = ; x<=; x++)//枚举的是当前位上的数
dp[l+][i+x][j][(k*+x)%j] += dp[l][i][j][k];
} //这个(k*10+x)%j是什么意思 //这个状态是前一个状态,位数比等号左边的少一位
//为什么要用k*10+x来模j呐
//因为吧,原来求的是前l位的和,
//现在求得是l+1位的和了,以前的位数
//都向左移动了一位
int solve(int n)
{
if(!n)
return ;
int ans,i,j,k,len;
int sum,tem1,tem2,s,bit[],r;
len = sum = ans = ;
tem1 = tem2 = n;
s = ;
while(tem1)//求每位数之和
{
bit[++len]=tem1%;
tem1/=;
sum+=bit[len];//每位数之和
}
if(n%sum==)//本身要先看是否整除
ans++;
for(i=;i<=len;i++)//前i位
{
sum-=bit[i];//将该位清0
tem2/=;//现在个数是没有个位的
s*=;
tem1=tem2*s;//现在这个数个位上的数是零
for(j=;j<bit[i];j++)//枚举该位的状况(就是遍历这个位上的数)
{
for(k=sum+j;k<=sum+j+*(i-);k++) //该位与更高位的和,而比该位低的和择优9*(i-1)种
{//9*(i-1)因为你枚举每多一位枚举的数字就会多出来9个
if(!k)//和为0的状况不符合
continue;
r=tem1%k;//这里是要保证你枚举到的前i位再加上没枚举到那些位加起来不会超过原来的数
if(r)
r=k-r;//余数大于0,那么k-r得到的数肯定能被k整除
ans+=dp[i-][k-sum-j][k][r];//加上个数
}
tem1+=s/;//标记现在算到哪里,例如1234,一开始t是1230,然后1231,1232,1233,1234,接下来1200,就是1210,1220,1230
}
}
return ans;
} int main()
{
//freopen("in.txt","r",stdin);
int T,l,r,cas = ;
set();//先打表,半打表,将前l位,位数之和是i,并且模上j之后得到k的个数有多少
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&l,&r);
printf("Case %d: %d\n",cas++,solve(r)-solve(l-));
}
return ;
}

自己又写了一遍,虽然都差不多,但是自己写一遍理清了思路

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#define N 10
#define M 82
using namespace std;
int dp[N][M][M][M],g[N];//dp[l][i][j][k]表示前l位的和为i 模上j得数是k的数有多少个
void inti()
{
for(int i=;i<=;i++)
dp[][][i][]=;
//cout<<"ok"<<endl;
for(int l=;l<;l++)//枚举的前l位
for(int i=;i<=l*;i++)//枚举的前l位的和
for(int j=;j<=;j++)//枚举的是你要模的那个数
for(int k=;k<j;k++)//枚举的是模完的结果
for(int x=;x<;x++)//枚举的第l+1位
dp[l+][i+x][j][(k*+x)%j]+=dp[l][i][j][k];
//cout<<"ok"<<endl;
//cout<<"ok"<<endl;
}
int solve(int n)
{
if(!n) return ;
int s,tem1,tem2,sum=,r;
tem1=tem2=n;
s=;
int len=;
while(tem1)
{
g[++len]=tem1%;
tem1/=;
sum+=g[len];
}//分离各位,并且求出来和
int cur=;
if(n%sum==)
cur++;
for(int i=;i<=len;i++)//模拟的是前i位
{
sum-=g[i];//先把这一位清零
tem2/=;
s*=;
tem1=s*tem2;
for(int j=;j<g[i];j++)//枚举的是这个位上的数
{
for(int k=sum+j;k<=sum+j+*(i-);k++)//模拟的是你要模的那个数
{
if(!k) continue;//如果k==0不符合条件
r=tem1%k;
if(r)
r=k-r;
cur+=dp[i-][k-sum-j][k][r];
//cout<<"cur="<<cur<<endl;
//cout<<"dp[i-1][k-sum-j][k][r]="<<dp[i-1][k-sum-j][k][r]<<endl;
}
tem1+=s/;
}
}
return cur;
}
int main()
{
//freopen("in.txt","r",stdin);
//cout<<"ok"<<endl;
inti();
int t,l,r;
scanf("%d",&t);
//cout<<t<<endl;
for(int i=;i<=t;i++)
{
scanf("%d%d",&l,&r);
//cout<<l<<" "<<r<<endl;
printf("Case %d: %d\n",i,solve(r)-solve(l-));
}
return ;
}

HDU X mod f(x)(题解注释)的更多相关文章

  1. HDU - 4389 X mod f(x)(数位dp)

    http://acm.hdu.edu.cn/showproblem.php?pid=4389 题意 为[A,B] 区间内的数能刚好被其位数和整除的数有多少个. 分析 典型的数位dp...比赛时想不出状 ...

  2. HDU 4389——X mod f(x)(数位DP)

    X mod f(x) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Probl ...

  3. HDOJ 4389 X mod f(x)

    数位DP........ X mod f(x) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  4. HDU4389:X mod f(x)(数位DP)

    Problem Description Here is a function f(x): int f ( int x ) { if ( x == 0 ) return 0; return f ( x ...

  5. hdu 4389 X mod f(x) 数位DP

    思路: 每次枚举数字和也就是取模的f(x),这样方便计算. 其他就是基本的数位Dp了. 代码如下: #include<iostream> #include<stdio.h> # ...

  6. HDU 4389 X mod f(x)

    题意:求[A,B]内有多少个数,满足x % f(x) == 0. 解法:数位DP.转化为ans = solve(b) - solve(a - 1).设dp[i][sum][mod][r]表示长度为i, ...

  7. HDU 2157 How many ways?? 题解

    题目 春天到了, HDU校园里开满了花, 姹紫嫣红, 非常美丽. 葱头是个爱花的人, 看着校花校草竞相开放, 漫步校园, 心情也变得舒畅. 为了多看看这迷人的校园, 葱头决定, 每次上课都走不同的路线 ...

  8. HDU 2815 Mod Tree 离散对数 扩张Baby Step Giant Step算法

    联系:http://acm.hdu.edu.cn/showproblem.php?pid=2815 意甲冠军: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQ ...

  9. hdu 2815 Mod Tree (exBSGS)

    http://acm.hdu.edu.cn/showproblem.php?pid=2815 //解 K^D ≡ N mod P #include<map> #include<cma ...

随机推荐

  1. 【个人笔记】《知了堂》node.js简介及创建应用

    Node.js是什么? Node.js是建立在谷歌Chrome的JavaScript引擎(V8引擎)的Web应用程序框架.Node.js自带运行时环境可在Javascript脚本的基础上可以解释和执行 ...

  2. Linux下利用expect,不用交互模式,直接登陆远程主机

    Linux环境下只有在机器20.200.254.18上ssh dataconv@20.200.31.23才能连接到23的机器,而且还需要输入密码(每次都需要输入地址,密码很烦),所以利用expect写 ...

  3. 策略模式Strategy

    定义一系列的算法,把他们封装起来,使得算法独立于适用对象. 比如,一个系统有很多的排序算法,但是使用哪个排序算法是客户对象的自有.因此把每一个排序当做一个策略对象,客户调用哪个对象,就使用对应的策略方 ...

  4. Coin Change (IV) (dfs)

    Coin Change (IV) Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu [Subm ...

  5. python---random模块使用详解

    random与随机操作有关的模块 常用方法: random() --- 返回0-1之见得一个随机浮点数. 调用:random.random() 例如: >>> random.rand ...

  6. PHP字符串函数-trim()实例用法

    string trim ( string $str [, string $charlist = " \t\n\r\0\x0B" ] )此函数返回字符串 str 去除首尾空白字符后的 ...

  7. javascript特效300例----抄书喽

    -javascript300例- #body_div { background-color: #202425; color: white; margin: 0 auto; border: 5px gr ...

  8. NSString与NSMutableString的浅拷贝与深拷贝

    浅拷贝:指针拷贝,指针与原指针地址相同,没有创建新的对象. 深拷贝:内容拷贝,创建了新的对象,指针地址与原对象的指针地址不同. NSString测试代码如下 打印结果如下(后面打印出的两个NSCFCo ...

  9. 在SQL中用正则表达式替换html标签(2)

    由于数据库的一个表字段中多包含html标签,现在需要修改数据库的字段把html标签都替换掉.当然我可以通过写一个程序去修改,那毕竟有点麻烦.直接在查询分析器中执行,但是MS SQL Server并没有 ...

  10. CSS滤镜效果

    使用 filter: blur() 生成毛玻璃效果 使用 filter: drop-shadow() 生成整体阴影效果 使用 filter: opacity() 生成透明度 blur生成阴影 通常我们 ...