数位DP。dp[i][j]表示i位,最高位为j的情况下总共有多少1.
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<map> #include<queue> #include<string> #include<vector> using namespace std; long long dp[15][15]; char s[20]; void init() { memset(dp,0,sizeof dp); long long num=1; for(int i=1; i<=10; i++) { for(int j=0; j<=9; j++) { if(j==1) dp[i][j]=num; for(int s=0; s<=9; s++) dp[i][j]=dp[i][j]+dp[i-1][s]; } num=num*10; } } int main() { init(); while(~scanf("%s",s)) { int len=strlen(s); long long n=0; for(int i=0; s[i]; i++) n=n*10+s[i]-'0'; long long ans=0; for(int i=0; i<s[0]-'0'; i++) ans=ans+dp[len][i]; for(int i=1; s[i]; i++) { int d=len-i; for(int j=0; j<s[i]-'0'; j++) ans=ans+dp[d][j]; } long long x=0; for(int i=0; s[i]; i++) { x=x*10+s[i]-'0'; if(s[i]=='1') { long long tmp=x; for(int j=i+1; s[j]; j++) tmp=tmp*10; ans=ans+n-tmp+1; } } printf("%lld ",ans); } return 0; }