/*
*Time: 93ms
*题目大意:
*        求i+(i+1)+(i+2)的结果对于有没有进位,没有进位的称为Simple Addition Expression
*        给定一个n,求i < n有多少个数可以称为simple Addition Expression.
*解题思路:
*        总共有786432个符合要求的数据。所以可以用暴力。
*        求出所有的满足的simple Addition Expression的数。之后用二分查找位置即可。
*/
View Code
  1 #include <iostream>
  2 #include <algorithm>
  3 #include <iterator>
  4 using namespace std;
  5 
  6 const int MAX = 1000000;
  7 int num[10], cnt;
  8 __int64 res[MAX];
  9 
 10 __int64 arrayToInt64(int arr[], int n)
 11 {
 12     __int64 digit = 1, sum = 0;
 13     for(int i = n; i >= 0; i--)
 14     {
 15         sum += arr[i] * digit;
 16         digit *= 10;
 17     }
 18     return sum;
 19 }
 20 
 21 void dfs(int digit)
 22 {
 23     if(digit != 9)
 24     {
 25         for(int i = 0; i < 4; i++)
 26         {
 27             num[digit] = i;
 28             dfs(digit + 1);
 29         }
 30     }
 31     else
 32     {
 33         for(int i = 0; i < 3; i++)
 34         {
 35             num[digit] = i;
 36             res[cnt++] = arrayToInt64(num, digit);
 37         }
 38     }
 39 
 40     return ;
 41 }
 42 
 43 void viewArr(__int64 a[], int n)
 44 {
 45     for(int i = 0; i < n; i++)
 46         cout << a[i] << endl;
 47     return ;
 48 }
 49 
 50 int countNum(__int64 n)
 51 {
 52     __int64 *p;
 53     p = lower_bound(res, res+ cnt, n);
 54     return p - res;
 55 }
 56 
 57 int main(void)
 58 {
 59     //freopen("in.txt", "r", stdin);
 60     cnt = 0;
 61     dfs(0);
 62     //viewArr(res, 10);
 63     __int64 n;
 64     while(scanf("%I64d", &n) == 1)
 65     {
 66         printf("%d\n", countNum(n));
 67     }
 68     return 0;
 69 }
 70 
 71 
 72 /*
 73 *Time: 0ms
 74 *还是不怎么理解这种做法
 75 */
 76 #include <stdio.h>
 77 #include <math.h>
 78 #include <string.h>
 79 char s[15];
 80 /*
 81 传入数组下标i和,从当前位置开始剩余的数组长度。
 82 */
 83 int solve(int i,int p)
 84 {
 85     if(p==1)
 86         return s[i]>'2'?3:s[i]-'0'+1;
 87     /*当前值大于3,当然就可以取遍0-3的数字,这样子排列组合出的数值也一定比它小*/
 88     if (s[i]>'3')
 89         return (int)pow(4.0,p-1)*3;
 90     else
 91     {
 92         /*如果s[i] = 2,则取0-1时,后面的数字可以取遍0-3,除个位为3*/
 93         int tem1 = (int)(pow(4.0,p-2)*3*(s[i]-'0'));
 94         /*s[i]取2时,后面的数值就又是一次迭代计算啦*/
 95         int tem2 = solve(i+1,p-1);
 96         return tem1+tem2;
 97     }
 98 }
 99 
100 int main()
101 {
102     int len;
103     __int64 n;
104     while (scanf("%I64d",&n)!=EOF)
105     {
106         n--;/*排列组合最大的数字就是n-1啦*/
107         sprintf(s,"%I64d",n);
108         len = strlen(s);
109         printf("%d\n",solve(0,len));
110     }
111     return 0;
112 }
posted on 2012-07-24 13:49  cchun  阅读(374)  评论(0编辑  收藏  举报