讲解:
http://blog.csdn.net/niuox/article/details/9864199
http://m.blog.csdn.net/article/details?id=52100392
第一题 http://acm.timus.ru/problem.aspx?space=1&num=1057
#include<bits/stdc++.h>
using namespace std;
int f[50][50],g[50];
int cal(int x,int k,int b)
{
int len=0,res=0;
while(x) g[++len]=x%b,x/=b;
for(int i=len;i;i--)
{
if(g[i]>1) res+=f[i-1][k]+f[i-1][k-1];
else if(g[i]==1) res+=f[i-1][k],k--;
if(k<0) return res;
}
return res;
}
int main()
{
int x,y,k,b;
for(int i=0;i<33;i++)
{
f[i][0]=1;f[i][1]=i;
for(int j=2;j<=i;j++) f[i][j]=f[i-1][j]+f[i-1][j-1];
}
scanf("%d%d%d%d",&x,&y,&k,&b);
printf("%d\n",cal(y+1,k,b)-cal(x,k,b));
return 0;
}
第二题 http://www.lydsy.com/JudgeOnline/problem.php?id=1026
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
int A[12];
int f[12][10];
//f[i][j]代表长度为i,最高位为j的windy数个数
void init()
{
memset(f,0,sizeof(f));
for(int i=0;i<10;i++) f[1][i] = 1;
for(int i=2;i<=10;i++)
{
for(int j=0;j<10;j++)
{
for(int k=0;k<10;k++)
{
if(abs(j-k)>1) f[i][j] += f[i-1][k];
}
}
}
}
//(0,a)范围内的windy数个数
int calc(int a)
{
int m = 0;
while(a)
{
A[m++] = a%10;
a/=10;
}
int ans = 0;
//先处理长度小于m的windy数的个数
for(int i=1;i<m;i++)
{
//题目要求不含前导0
for(int j=1;j<10;j++)
{
ans += f[i][j];
}
}
//长度等于m且最高位和原数不同且小于原数的windy数
for(int j=1;j<A[m-1];j++) ans += f[m][j];
//依次循环将最高位 变为和原数相同
for(int i=m-1;i>=1;i--)
{
for(int j=0;j<A[i-1];j++)
{
if(abs(j-A[i]) > 1) ans += f[i][j];
}
if(abs(A[i] - A[i-1])<=1) break;
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int a,b;
init();
while(scanf(" %d %d",&a,&b)!=EOF)
{
int ans = calc(b+1) - calc(a);
printf("%d\n",ans );
}
return 0;
}
第三题 http://acm.hdu.edu.cn/showproblem.php?pid=2089
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
typedef long long ll;
ll f[20][2],g[20];
ll dfs(int pos,int pre,int sta,bool limit)
{
if(pos==-1) return 1;
if(!limit&&f[pos][sta]!=-1) return f[pos][sta];
int up=limit?g[pos]:9;
ll res=0;
for(int i=0;i<=up;i++)
{
if(pre==6&&i==2) continue;
if(i==4) continue;
res+=dfs(pos-1,i,i==6,limit&&i==g[pos]);
}
if(!limit) f[pos][sta]=res;
return res;
}
ll cal(ll x)
{
ll pos=0;
while(x) g[pos++]=x%10,x/=10;
return dfs(pos-1,-1,0,1);
}
int main()
{
ll l,r;
memset(f,-1,sizeof f);
while(~scanf("%lld%lld",&l,&r),l|r)
{
printf("%lld\n",cal(r)-cal(l-1));
}
return 0;
}
第四题 http://acm.hdu.edu.cn/showproblem.php?pid=3555
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
typedef long long ll;
ll f[20][2],g[20];
ll dfs(int pos,int pre,int sta,bool limit)
{
if(pos==-1) return 1;
if(!limit&&f[pos][sta]!=-1) return f[pos][sta];
int up=limit?g[pos]:9;
ll res=0;
for(int i=0;i<=up;i++)
{
if(pre==4&&i==9) continue;
res+=dfs(pos-1,i,i==4,limit&&i==g[pos]);
}
if(!limit) f[pos][sta]=res;
return res;
}
ll solve(ll x)
{
ll pos=0;
while(x) g[pos++]=x%10,x/=10;
return dfs(pos-1,-1,0,1);
}
int main()
{
ll x,t;
scanf("%lld",&t);
memset(f,-1,sizeof f);
while(t--)
{
scanf("%lld",&x);
printf("%lld\n",x+1-solve(x));
}
return 0;
}
#include<bits/stdc++.h>// http://acm.hdu.edu.cn/showproblem.php?pid=3709
using namespace std;
const int N=1e3+10;
typedef long long ll;
ll f[20][20][2005],g[20];
ll dfs(int pos,int pre,int sum,bool limit)
{
if(pos<0) return sum==0;
if(sum<0) return 0;
if(!limit&&f[pos][pre][sum]!=-1) return f[pos][pre][sum];
int up=limit?g[pos]:9;
ll res=0;
for(int i=0;i<=up;i++)
{
res+=dfs(pos-1,pre,sum+i*(pos-pre),limit&&i==g[pos]);
}
if(!limit) f[pos][pre][sum]=res;
return res;
}
ll cal(ll x)
{
if(x<0) return 0;
ll len=0,res=0;
while(x) g[len++]=x%10,x/=10;
for(int i=0;i<len;i++)
res+=dfs(len-1,i,0,1);
return res-len+1;//排除掉0,00,000....这些情况
}
int main()
{
ll x,y,t;
scanf("%lld",&t);
memset(f,-1,sizeof f);
while(t--)
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",cal(y)-cal(x-1));
}
return 0;
}
#include<bits/stdc++.h>// http://acm.hit.edu.cn/hoj/problem/view?id=1983
using namespace std;
const int N=1e3+10;
typedef long long ll;
ll f[20][2525][55],g[20],ha[2525];
int gcd(int x,int y)
{
return y?gcd(y,x%y):x;
}
ll dfs(int pos,int mod,int lcm,bool limit)
{
if(pos<0) return mod%lcm==0;
if(!limit&&f[pos][mod][ha[lcm]]!=-1) return f[pos][mod][ha[lcm]];
int up=limit?g[pos]:9;
ll res=0;
for(int i=0;i<=up;i++)
{
res+=dfs(pos-1,(mod*10+i)%2520,i?(i*lcm/gcd(i,lcm)):lcm,limit&&i==g[pos]);
}
if(!limit) f[pos][mod][ha[lcm]]=res;
return res;
}
ll cal(ll x)
{
if(x<0) return 0;
ll len=0;
while(x) g[len++]=x%10,x/=10;
return dfs(len-1,0,1,1);
}
int main()
{
ll x,y,t;
memset(f,-1,sizeof f);
int id=0;
for(int i=1;i*i<2520;i++)
if(2500%i==0)
{
ha[i]=id++;
if(i*i!=2520) ha[2520/i]=id++;
}
while(~scanf("%lld%lld",&x,&y))
{
printf("%lld\n",cal(y)-cal(x-1));
}
return 0;
}
第七题 http://acm.hdu.edu.cn/showproblem.php?pid=4507
#include<bits/stdc++.h>// http://acm.hdu.edu.cn/showproblem.php?pid=4507
using namespace std;
const int N=1e3+10;
const int p=1e9+7;
typedef long long ll;
struct node
{
ll n,s,sq;
}f[20][10][10];
ll g[20],pw[2525];
node dfs(int pos,int mod,int sum,bool limit)
{
if(pos<0)
{
node tmp;
tmp.n=(mod!=0&&sum!=0);
tmp.s=tmp.sq=0;
return tmp;
}
if(!limit&&f[pos][mod][sum].n!=-1) return f[pos][mod][sum];
int up=limit?g[pos]:9;
node res,tmp;
res.n = res.s = res.sq = 0;
for(int i=0;i<=up;i++)
{
if(i==7) continue;
tmp=dfs(pos-1,(mod*10+i)%7,(sum+i)%7,limit&&i==g[pos]);
res.n=(res.n+tmp.n)%p;
res.s=(res.s+tmp.s+((i * pw[pos])%p * tmp.n) % p) % p ;
res.sq=(res.sq+tmp.sq+((2*i*pw[pos])%p*tmp.s)%p +
(((i*i*pw[pos])%p*pw[pos])%p*tmp.n)%p)%p;
}
if(!limit) f[pos][mod][sum]=res;
return res;
}
ll cal(ll x)
{
if(x<0) return 0;
ll len=0;
while(x) g[len++]=x%10,x/=10;
return dfs(len-1,0,0,1).sq;
}
int main()
{
ll x,y,t;
memset(f,-1,sizeof f);
pw[0]=1;
for(int i=1;i<=19;i++)
{
pw[i]=(pw[i-1]*10)%p;
}
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",(cal(y)-cal(x-1)+p)%p);
}
return 0;
}
第八题 https://www.bnuoj.com/v3/problem_show.php?pid=52325 (他的oj现在好像过不去了)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//位数 数字 关系
ll f[20][10][5],sum[20],g[20];
ll dfs(ll pos,ll num,ll lis,ll flag)
{
if(pos<=0) return 1;
if(f[pos][num][lis]!=-1&&!flag) return f[pos][num][lis];
ll x=flag?g[pos]:9;
ll res=0;
for(ll i=0;i<=x;i++)
{
if(i<=num&&lis==0) res+=dfs(pos-1,i,0,flag&&(i==x));
if(i==num&&lis==1) res+=dfs(pos-1,i,1,flag&&(i==x));
if(i>=num&&lis==2) res+=dfs(pos-1,i,2,flag&&(i==x));
}
if(!flag) f[pos][num][lis]=res;
return res;
}
ll solve(ll x)
{
ll res=0,pos=0;
memset(g,0,sizeof g);
while(x)
{
g[++pos]=x%10;
x/=10;
}
pos--; x=g[pos+1];
for(ll i=1;i<x;i++)
res+=dfs(pos,i,0,0)+dfs(pos,i,2,0)-dfs(pos,i,1,0);
res+=dfs(pos,x,0,1)+dfs(pos,x,2,1)-dfs(pos,x,1,1);
return res+sum[pos];
}
int main()
{
ll t,tt=0,x=0,y,z;
memset(f,-1,sizeof f);
for(ll i=1;i<20;i++)
{
x=x*10+9;
sum[i]=solve(x);
}
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",solve(y)-solve(x-1));
}
}
第九题 http://gdutcode.sinaapp.com/problem.php?cid=1057&pid=6
#include<bits/stdc++.h>
using namespace std;
const int N=20000+10;
const int inf=0x3f3f3f3f;
typedef long long ll;
ll f[20][20][10][2][2][2],g[20],num[20];
//代表当前第 位上一位是什么,增过,减过, 长度为 len 回文?
ll rec(int pos,int pre,int up,int down,int flag,int q,int len,int ispa)
{
if(pos<0) return up&&down&&ispa;
if(~f[pos][len][pre][up][down][ispa]&&!flag&&!q)
return f[pos][len][pre][up][down][ispa];
ll x=flag?g[pos]:9;
ll res=0;
for(int i=0;i<=x;i++)
{
num[pos]=i;
if(q) res+=rec(pos-1,i,0,0,i<x?0:flag,q&&i==0,len-(q&&i==0),ispa);
else if(i==pre)
{
if(ispa&&pos<len/2)
res+=rec(pos-1,i,up,down,i<x?0:flag,q&&i==0,len,i==num[len-pos-1]);
else res+=rec(pos-1,i,up,down,i<x?0:flag,q&&i==0,len,ispa);
}
else if(i>pre)
{
if(!down) continue;
if(ispa&&pos<len/2)
res+=rec(pos-1,i,1,down,i<x?0:flag,q&&i==0,len,i==num[len-pos-1]);
else res+=rec(pos-1,i,1,down,i<x?0:flag,q&&i==0,len,ispa);
}
else if(i<pre)
{
if(up) continue;
if(ispa&&pos<len/2)
res+=rec(pos-1,i,up,1,i<x?0:flag,q&&i==0,len,i==num[len-pos-1]);
else res+=rec(pos-1,i,up,1,i<x?0:flag,q&&i==0,len,ispa);
}
}
if(!flag&&!q) f[pos][len][pre][up][down][ispa]=res;
return res;
}
ll cal(ll x)
{
int len=0;
while(x) g[len++]=x%10,x/=10;
return rec(len-1,0,0,0,1,1,len,1);
}
int main()
{
ll t,l,r;
memset(f,-1,sizeof f);
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld",&l,&r);
printf("%lld\n",cal(r)-cal(l-1));
}
return 0;
}