POJ - 1850 Code(组合数学)
https://vjudge.net/problem/POJ-1850
题意
输出某字符串在字典中的位置。字符串不合规则时输出0。
分析
首先判断字符串合法性,也就是判断是不是升序排列的。如果符合,以“vwxyz”为例,先计算长度小于5的串。
长度为1:C(26,1)
长度为2:由于规定了是升序序列,那么只要字母确定了,排列的情况也就确定了,于是此时可以认为方案数就等于从26个字母里任选两个出来,即C(26,2),经验证也是正确的。
长度为3:同上,C(26,3),长度为4:C(26,4)。
接下来是计算相同长度的,这里逐位来计算比较方便,例如从第0位开始(’v‘),计算aXXXX,bXXXX……uXXXX。然后第1位(‘w'),计算aXXX,bXXX……vXXX。以此类推,详细看代码就懂了。最后答案就是以上得到的总和+1。
预处理组合数用递推的方法。
#include<iostream> #include<cmath> #include<cstring> #include<queue> #include<vector> #include<cstdio> #include<algorithm> #include<map> #include<set> #define rep(i,e) for(int i=0;i<(e);i++) #define rep1(i,e) for(int i=1;i<=(e);i++) #define repx(i,x,e) for(int i=(x);i<=(e);i++) #define X first #define Y second #define PB push_back #define MP make_pair #define mset(var,val) memset(var,val,sizeof(var)) #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define pd(a) printf("%d\n",a) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define IOS ios::sync_with_stdio(false);cin.tie(0) using namespace std; typedef long long ll; template <class T> void test(T a){cout<<a<<endl;} template <class T,class T2> void test(T a,T2 b){cout<<a<<" "<<b<<endl;} template <class T,class T2,class T3> void test(T a,T2 b,T3 c){cout<<a<<" "<<b<<" "<<c<<endl;} const int N = 1e6+10; //const int MAXN = 210; const int inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3fll; const ll mod = 1000000007; int T; void testcase(){ printf("Case #%d: ",++T); } const int MAXN = 3e5+5; const int MAXM = 30; int c[30][30]; void init(){ mset(c,0); for(int i=0;i<30;i++){ c[i][0]=1; for(int j=1;j<=i;j++){ c[i][j]=c[i-1][j-1]+c[i-1][j]; } } } char a[15]; int main() { #ifdef LOCAL freopen("data.in","r",stdin); #endif // LOCAL init(); scanf("%s",a); int len = strlen(a); for(int i=1;i<len;i++){ if(a[i-1]>=a[i]){ puts("0"); return 0; } } ll ans=0; for(int i=1;i<len;i++) ans+=c[26][i]; for(int i=0;i<len;i++){ char ch = (!i)?'a':a[i-1]+1; while(ch<=a[i]-1){ ans+=c['z'-ch][len-i-1]; ch++; } } cout<<ans+1; return 0; }