标签:style blog http color io ar for div html
http://acm.tju.edu.cn/toj/showp1183.html
题意:从a写到b,问每个数字各写了几次。
分析:昨天做了一道how many 0‘s,这题算是拓展。考虑从0..a。1到9是一样的,如果目前考虑的是digit,枚举每位,左边填0..x-1,则右边随便填(10^右边长度),左边填x,如果a的当前位大于digit,那么右边还是随便填,如果等于,只能填0..右边最大值,如果大于则没有。而0不一样在于不能作为一个数的第一位,所以左边只能填1..x-1,还有如果目前枚举的是最高位则不能填0。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 #define debug 0 7 int beg, end; 8 int d[20]; 9 int ans1[15], ans2[15]; 10 void cal(int x, int ans[]) 11 { 12 for (int i = 0; i < 10; i++) ans[i] = 0; 13 if (x == -1) return; 14 if (x == 0){ 15 ans[0] = 1; 16 return; 17 } 18 int len = 0; 19 int xx = x; 20 while(x){ 21 d[len++] = x % 10; 22 x /= 10; 23 } 24 x = xx; 25 for (int digit = 1; digit <= 9; digit ++){ 26 int sum = 0, res = x/10, cnt = 0, exp = 1; //res为当前位的左边,cnt为右边,exp为右边随便填的总数 27 for (int i = 0; i < len; i++){ 28 sum = sum + res * exp; //左边填0..res-1,右边随便填 29 if (digit < d[i]) sum = sum + exp; //如果小于,左边填res,右边随便填 30 else if (digit == d[i]) sum = sum + cnt+1; //相等,即左边到当前位都是在最高的情况,右边只能填0..cnt 31 32 if (debug){ 33 if (digit == 4) printf("%d\n",sum); 34 } 35 cnt = cnt + d[i] * exp; 36 exp *= 10; 37 res /= 10; 38 } 39 ans[digit] = sum; 40 } 41 int sum = 1, res = x/10, cnt = 0, exp = 1; 42 for (int i = 0; i < len; i++){ 43 if (res > 0) sum = sum + (res-1) * exp; //单独算为0的情况,一个是左边从1开始,还有一个是最高位不能填0 44 if (d[i]) { 45 if (i != len-1) sum = sum + exp; 46 } 47 else sum = sum + cnt + 1; 48 cnt = cnt + d[i] * exp; 49 exp *= 10; 50 res /= 10; 51 } 52 ans[0] = sum; 53 } 54 int main() 55 { 56 while(scanf("%d %d", &beg, &end)) 57 { 58 if (beg == 0 && end == 0) break; 59 if (beg > end) swap(beg, end); 60 cal(beg-1, ans1); 61 cal(end, ans2); 62 if (debug) for (int i = 0; i < 10; i++) printf("%d %d\n", ans1[i], ans2[i]); 63 for (int i = 0; i < 10; i++) printf("%d%c", ans2[i]-ans1[i], i==9? ‘\n‘: ‘ ‘); 64 } 65 return 0; 66 }
TOJ 1183 The Counting Problem 数位dp
标签:style blog http color io ar for div html
原文地址:http://www.cnblogs.com/james47/p/3945519.html