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 }