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;
}

 

posted @ 2018-07-02 09:51  litos  阅读(288)  评论(0编辑  收藏  举报