题意:
定义s为只由26个小写英文字母组成的长度任意的串,且串中的字母严格升序。
定义集合S为长度10以下的s的集合,S中的元素优先按照串的长度排序,长度相同按照字典序排序。
输入一个串str,若str在S中则输出str是S的第几小,若str不在S中输出0
思路:
组合数
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; char s[20]; long long c[50][50], len[50]; void init() { c[0][0] = 1; for (int i = 1; i <= 26; i++) { c[i][0] = 1; for (int j = 1; j <= i; j++) { c[i][j] = c[i-1][j] + c[i-1][j-1]; } } len[0] = 0; for (int i = 1; i <= 10; i++) len[i] = len[i-1] + c[26][i]; } int main() { init(); while (~scanf("%s", s)) { int n = strlen(s); bool ok = true; for (int i = 0; i < n - 1; i++) if (s[i] >= s[i+1]) { ok = false; break; } if (!ok) { printf("0\n"); continue; } long long ans = 1; for (int i = 0, j = 0; i < n; i++) { int x = s[i] - 'a'; if (i) j = s[i-1] - 'a' + 1; for (; j < x; j++) ans += c[26-(j+1)][n-i-1]; } printf("%lld\n", ans + len[n - 1]); } return 0; }