标签:read als 处理 long std ace fine nbsp turn
题意:给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。
经历一中午,终于TM做出来了
满满的成就。。。
以f[i][j][k]代表长度为i最高位为j数码k出现几次
修正:
1、预处理
若最高位j==k 还得加上10的i次幂
2、求
同1,若当前位的上一位跟所求数码相同
也要加上它乘10的次幂
然而之后
WA
WA
WA
。。。
找到一个坑101
我输出了111
在2加次幂时,没有同步减去中间数,导致过大
详情见代码QAQ
#include<cstdio> #include<iostream> using namespace std; #define int long long int f[50][20][20]; int base[20]; int a,b; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch==‘-‘) f=-f; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline void put(int x) { if(x<0) { putchar(‘-‘); x=-x; } if(x>9) put(x/10); putchar(x%10+‘0‘); } inline void init() { for(int i=0;i<=9;i++) f[1][i][i]=1; base[0]=1; for(int i=1;i<=15;i++) base[i]=base[i-1]*10; for(int i=2;i<=14;i++) { for(int j=0;j<=9;j++) for(int l=0;l<=9;l++) for(int k=0;k<=9;k++) f[i][j][l]+=f[i-1][k][l]; for(int k=0;k<=9;k++) f[i][k][k]+=base[i-1]; } } inline int work(int x,int dig) { int ans=0; int len=1; int olinr=x-1; bool flag=true; while(x>=base[len])len++; for(int i=1;i<len;i++) for(int j=1;j<=9;j++) ans+=f[i][j][dig]; int lst=0x7fffffff; for(int i=len;i>=1;i--) { int tp=(x/base[i-1])%10; for(int j=flag;j<tp;j++) ans+=f[i][j][dig]; if(!flag) { if(lst==dig) { ans+=olinr-(dig*base[i])+1; } olinr-=base[i]*lst; //原来放在if里面,坑死了。。。。 } flag=false; lst=tp; } return ans; } signed main() { a=read(); b=read(); init(); for(int i=0;i<=9;i++) { put(work(b+1,i)-work(a,i)); putchar(‘ ‘); } return 0; }
标签:read als 处理 long std ace fine nbsp turn
原文地址:https://www.cnblogs.com/olinr/p/9418442.html