#include<cstdio> #include<cstring> #include<algorithm> usingnamespace std; #define re register #define int long long constint MAXn = 50;
int C[MAXn + 10][MAXn + 10]; voidEvaC(int top){ for (re int i = 0; i <= top; ++i) { C[i][0] = C[i][i] = 1; } for (re int i = 1; i <= top; ++i) { for (re int j = 1; j < i; ++j) { C[i][j] = C[i - 1][j - 1] + C[i - 1][j]; } } }
intPmult(int top, int *cnt, int sum = -1){ int ans = 1; if (sum == -1) { sum = 0; for (re int i = 1; i <= top; ++i) { sum += cnt[i]; } } for (re int i = 1; i <= top; ++i) { if (cnt[i]) { ans *= C[sum][cnt[i]]; sum -= cnt[i]; } } return ans; }
char str[MAXn + 10]; int len; int sumcnt, cnt[11], ans; // cnt[x]: "x"数还可参与排列的数量,也就是"x"在当前位和比当前位低的位中的数量。 // cnt[10]: 在当前位和比当前位低的位中"0"的数量。 // sumcnt: Sum{cnt[1] ~ cnt[9]},用于计算"0"的个数。 signedmain(){ EvaC(MAXn); scanf("%s", str + 1); len = strlen(str + 1); reverse(str + 1, str + 1 + len); for (re int i = 1; i <= len; ++i) { if (str[i] - '0') { ++cnt[str[i] - '0']; ++sumcnt; } } for (re int i = len; i; --i) { if (str[i] - '0') { cnt[10] = i - 1 - sumcnt; ans += Pmult(10, cnt, i - 1); cnt[10] = i - 1 - (sumcnt - 1); for (re int j = 1; j < str[i] - '0'; ++j) { if (cnt[j]) { --cnt[j]; ans += Pmult(10, cnt, i - 1); ++cnt[j]; } } --cnt[str[i] - '0']; --sumcnt; } } printf("%lld\n", ans); }