#include<bits/stdc++.h>usingnamespace std;//f[i][j]:以数码j开头的i位数中不降数的个数 //f[3][0]:以0开头的3位数中不降数的个数,范围指的是[000, 099],有55个//f[3][1]:以1开头的3位数中不降数的个数,范围指的是[100, 199],有45个int f[20][20];//返回[0, x]中不降数的个数 intfun(int x){if(x ==0)return1;//特判:[0,0]中不降数有1个 int n =0, a[20]={};//x是n位数,分离各位数,放在a数组, 例如: 2147483647, a[10] ~ a[1]while(x) a[++ n]= x %10, x /=10;int res =0;for(int i = n; i >=1; i --){for(int j = a[i +1]; j < a[i]; j ++){//e.g.x = 367, 先统计000~099, 100~199, 200~299中不降数的个数
res += f[i][j];}if(a[i +1]> a[i])break;//下降了,结束循环 if(i ==1) res ++;//x本身是个不降数 }return res;}intmain(){for(int j =0; j <=9; j ++) f[1][j]=1;//以数码j开头的1位数中不降数的个数 for(int i =2; i <=10; i ++){//递推2位数 ~ 10位数 //i位数,前两位是jk,for(int j =0; j <=9; j ++){for(int k = j; k <=9; k ++){//因为不降,所以k >= j
f[i][j]+= f[i -1][k];}}}int a, b;while(cin >> a >> b){
cout <<fun(b)-fun(a -1)<< endl;}return0;}
Windy数
#include<bits/stdc++.h>usingnamespace std;int f[20][20];//f[i][j]:以数码j开头的i位数中的Windy数的个数 intfun(int x){if(x ==0)return0;//0不是Windy数 int n =0, a[20]={};while(x) a[++ n]= x %10, x /=10;
a[n +1]=-1;//左边哨兵,因为最高位从1开始,要满足相邻不小于2 int res =0;//eg, x = 365, 先统计[1,9], [10,99]中Windy数的个数 for(int i =1; i < n; i ++){for(int j =1; j <=9; j ++){
res += f[i][j];}}for(int i = n; i >=1; i --){//,通过哨兵,保证最高位从1开始,其它位从0开始 for(int j =0; j < a[i]; j ++){if(abs(j - a[i +1])>=2){
res += f[i][j];}}//eg, x = 34..., 统计完30..., 31..., 就停止循环 if(abs(a[i]- a[i +1])<2)break;if(i ==1) res ++;}return res;}intmain(){//注意,递推的时候,还是要从数码0开始 for(int j =0; j <=9; j ++) f[1][j]=1;for(int i =2; i <=10; i ++){//i位数,前两位是jk,for(int j =0; j <=9; j ++){for(int k =0; k <=9; k ++){if(abs(k - j)>=2){
f[i][j]+= f[i -1][k];}}}}int a, b;while(cin >> a >> b){
cout <<fun(b)-fun(a -1)<< endl;}return0;}
不要 62
#include<bits/stdc++.h>usingnamespace std;//要统计的数字:不含62,不含4 //f[i][j]:i位数,以数码j开头,符合条件的数字的个数 int f[20][20];intfun(int x){if(x ==0)return1;//0符合条件 int n =0, a[10]={};while(x) a[++ n]= x %10, x /=10;int res =0;for(int i = n; i >=1; i --){for(int j =0; j < a[i]; j ++){if(j ==4)continue;if(a[i +1]==6&& j ==2)continue;
res += f[i][j];}if(a[i]==4)break;if(a[i +1]==6&& a[i]==2)break;if(i ==1) res ++;}return res;}intmain(){for(int j =0; j <=9; j ++){//1位数 if(j ==4)continue;
f[1][j]=1;}for(int i =2; i <=10; i ++){//i位数,前两位数是jk for(int j =0; j <=9; j ++){if(j ==4)continue;for(int k =0; k <=9; k ++){if(k ==4)continue;if(j ==6&& k ==2)continue;
f[i][j]+= f[i -1][k];}}}int l, r;while(cin >> l >> r, l || r){
cout <<fun(r)-fun(l -1)<< endl;}return0;}
Amount of Degrees
#include<bits/stdc++.h>usingnamespace std;int x, y, k, b;//max = 2^31-1,最多有31位b进制, 组合数C[i][j], 表示i位b进制数中有k个1的个数 int C[40][40];intfun(int x){if(x ==0)return0;int n =0, a[40]={};while(x) a[++ n]= x % b, x /= b;int res =0, cnt =0;//前面已经出现了cnt个1 for(int i = n; i >=1; i --){if(a[i]>1){
res += C[i][k - cnt];//i位数有(k - cnt)个1的数字的个数 break;}elseif(a[i]==1){//如果x的第i位上的数字是1,那么在树上产生两个分支 //分支1:第i位是0,接下来统计后i-1位数有(k - cnt)个1的数字的个数
res += C[i -1][k - cnt];//分支2:第i位是1,接下来统计后i-1位数有(k - cnt - 1)个1的数字的个数
cnt ++;if(cnt == k){
res ++;break;}}else{//如果x的第i位上的数字是0,则不会对res产生贡献,从下一位继续枚举 }}return res;}intmain(){
cin >> x >> y >> k >> b;for(int i =0; i <=31; i ++){for(int j =0; j <= i; j ++){if(!j) C[i][j]=1;else C[i][j]= C[i -1][j -1]+ C[i -1][j];}}
cout <<fun(y)-fun(x -1)<< endl;return0;}
数字游戏2,模N为0
#include<bits/stdc++.h>usingnamespace std;int a, b, N;int f[20][20][109];//f[i][j][x]: 以数码j开头的i位数,各位数字之和模N为x的数的个数 intfun(int x){if(x ==0)return1;//0符合条件 int n =0, a[20]={};while(x) a[++ n]= x %10, x /=10;int res =0, sum =0;//sum, 表示i左边的数之和 % N for(int i = n; i >=1; i --){for(int j =0; j < a[i]; j ++){
res += f[i][j][(N - sum)% N];}
sum =(sum + a[i])% N;if(i ==1&& sum ==0) res ++;}return res;}intmain(){while(cin >> a >> b >> N){memset(f,0,sizeof(f));for(int j =0; j <=9; j ++) f[1][j][j % N]=1;for(int i =2; i <=10; i ++){//i位数,以 jk 开头 for(int j =0; j <=9; j ++){for(int k =0; k <=9; k ++){for(int x =0; x < N; x ++){//数字265, N = 9,f[3][2][4] += f[2][6][2], k不变 //数字266,N = 9, f[3][2][4] += f[2][6][3]//数字265, N = 9,f[3][2][4] += f[2][6][2], x不变 //数字274,N = 9, f[3][2][4] += f[2][7][2]
f[i][j][(j + x)% N]+= f[i -1][k][x];}}}}
cout <<fun(b)-fun(a -1)<< endl;}return0;}