http://acm.buaa.edu.cn/problem/364/
n位数 首位确定
从0-9选出2个 填到n-1个格子方法
a = 9 * (2 ^ (n - 1) - 2) 种
从0-9选出1个 填到n-1个格子方法
b = 10 种
因此10 ^ n 到 (10 ^ (n + 1) - 1)
共有 9 * (a + b) 种
以下SB逻辑 我已经不记得怎么想的了......
#include <iostream>
#include <cstring>
using namespace std;
int f[] = {99,351,927,2151,4671,9783,20079};
char a[10];
int getr(char arr[], int l, int u, int p, int q)
{
if(l > u) return 0;
int tot(0);
int c = (int)(arr[l] - '0');
if(p == q)
{
if(l == u) return c + 1;
tot = c << (u - l);
if(c > p)
tot += (8 << (u - l)) - 8;
if(c > p) q = c;
else p = c;
}
else
{
if(c < p) return 0;
if(l == u)
{
if(c >= q) return 2;
else return 1;
}
if(c > p && c < q) return 1 << (u - l);
if(c > q) return 1 << (u - l + 1);
if(c == q) tot = 1 << (u - l);
}
return tot + getr(arr, l + 1, u, p, q);
}
int main()
{
while(cin >> a)
{
int n = strlen(a);
switch(n)
{
case 1:
cout << a[0] << endl;
break;
case 2:
cout << a[0] << a[1] << endl;
break;
case 10:
cout << 40744 << endl;
break;
default:
int tot = f[n - 3];
int a1 = (int)(a[0] - '0');
tot += (10 + 9 * ((1 << (n - 1)) - 2)) * (a1 - 1);
tot += getr(a, 1, n - 1, a1, a1);
cout << tot << endl;
break;
}
}
}