入门题
HDU 2089 http://acm.hdu.edu.cn/showproblem.php?pid=2089
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
using namespace std;
typedef long long ll;
#define maxn 10
int dp[maxn][2]; //dp[0][i] 吉利数次 ,dp[1][i] 末尾是6的吉利数字<=>开头时2的吉利数字
void get_dp(){
dp[0][0]=1;
dp[0][1]=0;
dp[1][0]=9;
dp[1][1]=1;
for(int i=2;i<maxn;i++){
dp[i][0]=dp[i-1][0]*9-dp[i-1][1];
dp[i][1]=dp[i-1][0]+dp[i][1];
}
}
int solve(int n){
if(n<0) return 0;
int q[maxn],lq=0,ans=0;
while(n>0){q[lq++]=n%10;n/=10;}
q[lq]=0;
bool mark=1;
for(int i=lq-1;i>=0;i--){
if(!mark) continue;
if(q[i]==4||(q[i+1]==6&&q[i]==2)) mark=0;
if(q[i]<5) ans+=q[i]*dp[i][0]; // axxx
else if(q[i]<7) ans+=(q[i]-1)*dp[i][0]; // axxx-4xxx
else ans+=(q[i]-1)*dp[i][0]-dp[i][1]; // axxx-4xxx-62xx
if(q[i+1]==6&&q[i]>2) ans-=dp[i][0]; // -2xxx
}
if(mark) ans++;
return ans;
}
int main(){
int l,r;
get_dp();
while(scanf("%d%d",&l,&r),l!=0||r!=0){
printf("%d\n",solve(r)-solve(l-1));
}
}
HDU 3555 http://acm.hdu.edu.cn/showproblem.php?pid=3555
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define maxn 20
typedef long long ll;
ll dp[maxn][2]; //dp[i][0] i位有几个不包含49的 dp[i][1] 9 为首位的不含49的数量
void get_dp(){
dp[0][0]=1;
dp[0][1]=0;
dp[1][0]=10;
dp[1][1]=1;
for(int i=2;i<maxn;i++){
dp[i][0]=dp[i-1][0]*10-dp[i-1][1];
dp[i][1]=dp[i-1][0];
}
}
ll solve(ll n){
int p[maxn],lp=0;
ll ans=0;
while(n>0){
p[lp++]=n%10;
n/=10;
}
p[lp]=0;
bool mark=1;
for(int i=lp-1;i>=0;i--){
if(!mark) continue;
if(p[i+1]==4&&p[i]==9) mark=0;
if(p[i]<5) ans+=p[i]*dp[i][0];
else ans+=p[i]*dp[i][0]-dp[i][1];
}
if(mark) ans++;
return ans;
}
int main(){
get_dp();
int t;
ll n;
scanf("%d",&t);
while(t--){
scanf("%I64d",&n);
printf("%I64d\n",n+1-solve(n));
}
}
HDU 3652 http://acm.hdu.edu.cn/showproblem.php?pid=3652
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define maxn 20
typedef long long ll;
#define A 11 //位数
#define B 13 //mod 13 的余数
#define C 3 // 0不含有13 ,1 含有 13 的 ,2 首位是3不含有13 xxxxx 3xxxx
int dp[A][B][C];
void get_dp(){
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;
for(int i=0;i<10;i++)
dp[1][i][0]=1;
dp[1][3][2]=1;
int pul=1;
for(int i=2;i<=A;i++){
pul*=10;
for(int j=0;j<B;j++){
for(int k=0;k<10;k++){
dp[i][(j+k*pul)%B][0]+=dp[i-1][j][0];
dp[i][(j+k*pul)%B][1]+=dp[i-1][j][1];
}
dp[i][(j+pul)%B][0]-=dp[i-1][j][2];
dp[i][(j+pul)%B][1]+=dp[i-1][j][2];
dp[i][(j+3*pul)%B][2]+=dp[i-1][j][0];
}
}
}
int solve(int n){
if(n<=0) return 0;
int q[A],lq=0,ans=0,pul=1;
while(n>0){
q[lq++]=n%10;
n/=10;
pul*=10;
}
pul/=10;
q[lq]=0;
bool mark=0;
int mod=0;
for(int i=lq-1;i>=0;i--){
for(int j=0;j<q[i];j++){
for(int k=0;k<B;k++){
if((mod+j*pul+k*(pul/10))%B==0){
ans+=dp[i][(k*(pul/10))%B][1];
if(mark) ans+=dp[i][(k*(pul/10))%B][0]; // 之前有13
else if(q[i+1]==1){
if(j==3) ans+=dp[i][(k*(pul/10))%B][0];//前一位是1
else if(j==1) ans+=dp[i][(k*(pul/10))%B][2];
}
else{ //其他
if(j==1) ans+=dp[i][(k*(pul/10))%B][2];
}
}
if(i==0) break;
}
}
if(q[i+1]==1&&q[i]==3)
mark=1;
mod=(mod+q[i]*pul)%B;
pul/=10;
}
if(mark&&mod==0) ans++;
return ans;
}
int main(){
get_dp();
int n;
while(scanf("%d",&n)!=EOF)
printf("%d\n",solve(n));
}
HDU 3709 http://acm.hdu.edu.cn/showproblem.php?pid=3709
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
using namespace std;
typedef long long ll;
#define maxn 10
#define A 20
#define B 20
#define C 4000
ll dp[A][B][C]; // 平衡位置,第几位,差值
void get_dp(){
memset(dp,0,sizeof(dp));
for(int i=0;i<A;i++) dp[i][0][C/2]=1; dp[1][0][C/2]=1;
for(int i=0;i<A;i++)
for(int j=0;j<B-1;j++)
for(int k=0;k<C;k++){
if(dp[i][j][k]==0)
continue;
for(int p=0;p<10;p++)
dp[i][j+1][k+p*(j+1-i)]+=dp[i][j][k];
}
}
ll solve(ll n){
if(n<0) return 0;
if(n==0) return 1;
int q[B],lq=0;
ll ans=0;
while(n>0){
q[lq++]=n%10;
n/=10;
}
int cas[A]; memset(cas,0,sizeof(cas));
for(int i=lq-1;i>=0;i--){ //第几位
for(int j=1;j<A;j++){ // 平衡位置在哪
for(int k=0;k<q[i];k++) // 小于它的数
{
ans+=dp[j][i][C/2-cas[j]-(i+1-j)*k];
}
}
for(int j=0;j<A;j++)
cas[j]+=(i+1-j)*q[i];
}
for(int i=0;i<A;i++)
if(cas[i]==0) ans++;
ans=ans-A+2;
return ans;
}
int main(){
int t;
scanf("%d",&t);
ll l,r;
get_dp();
while(t--){
scanf("%I64d%I64d",&l,&r);
printf("%I64d\n",solve(r)-solve(l-1));
}
}
HDU 3943 http://acm.hdu.edu.cn/showproblem.php?pid=3943
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
using namespace std;
typedef long long ll;
#define maxn 21
ll dp[20][maxn][maxn];
void get_dp(){
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;
for(int i=1;i<20;i++)
for(int j=0;j<maxn;j++)
for(int k=0;k<maxn;k++){
dp[i][j][k]+=dp[i-1][j][k]*8;// dp[2][1][0]=dp[1][1][0]*10+dp[1][0][0];
if(j!=0) dp[i][j][k]+=dp[i-1][j-1][k];
if(k!=0) dp[i][j][k]+=dp[i-1][j][k-1];
}
}
ll solve(int a,int b,ll n){
int q[maxn],lq=0;
ll ans=0;
while(n>0){
q[lq++]=n%10;
n/=10;
}
for(int i=lq-1;i>=0;i--){
for(int j=0;j<q[i];j++){
if(j==4) {if(a!=0) ans+=dp[i][a-1][b];}
else if(j==7) {if(b!=0) ans+=dp[i][a][b-1];}
else ans+=dp[i][a][b];
}
if(q[i]==4) a--;
if(q[i]==7) b--;
if(a<0||b<0) break;
}
if(a==0&&b==0) ans++;
return ans;
}
int main(){
int t,cas=1;
scanf("%d",&t);
int x,y;
ll p,q;
get_dp();
while(t--){
scanf("%I64d%I64d%d%d",&p,&q,&x,&y);
ll n1=solve(x,y,p);
ll n2=solve(x,y,q);
int m;
scanf("%d",&m);
printf("Case #%d:\n",cas++);
while(m--){
ll n;
scanf("%I64d",&n);
if(n>n2-n1){printf("Nya!\n"); continue;}
n=n+n1;
ll st=p,nd=q;
while(st<=nd){
ll mid=(st>>1)+(nd>>1);
if(st%2==1&&nd%2==1) mid++;
ll temn=solve(x,y,mid);
if(temn>=n) nd=mid-1;
else st=mid+1;
}
printf("%I64d\n",st);
}
}
}
HDU 4389 http://acm.hdu.edu.cn/showproblem.php?pid=4389
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
using namespace std;
typedef long long ll;
#define A 11
#define B 91
#define C 91
int dp[A][B][C][C]; // 位 和 模数 余数
void get_dp(){
memset(dp,0,sizeof(dp));
for(int i=0;i<C;i++)
dp[0][0][i][0]=1;
for(int i=0;i<A-1;i++){
for(int j=0;j<=i*9;j++){
for(int k=0;k<C;k++){
for(int p=0;p<k||p==0;p++){
if(dp[i][j][k][p]==0) continue;
for(int t=0;t<10;t++){
int mod;
if(k==0) mod=0;
else mod=(p*10+t)%k;
dp[i+1][j+t][k][mod]+=dp[i][j][k][p];
}
}
}
}
}
}
int solve(int n){
n++;
int q[A],lq=0;
int ans=0;
int pul=1;
while(n>0){
q[lq++]=n%10;
n/=10;
pul*=10;
}
int sum=0;
int ssum=0;
for(int i=lq-1;i>=0;i--){
for(int j=0;j<=i*9;j++){
for(int k=0;k<q[i];k++){
int mod;
int J=j+k+ssum;
if(J) mod=(J-(k*(pul/10)+sum*pul)%J)%J;
else mod=0;
ans+=dp[i][j][J][mod];
}
}
sum=sum*10+q[i];
ssum+=q[i];
pul/=10;
}
return ans;
}
int main(){
int t,cas=1;
scanf("%d",&t);
int l,r;
get_dp();
while(t--){
scanf("%d%d",&l,&r);
printf("Case %d: %d\n",cas++,solve(r)-solve(l-1));
}
}