POJ 1850 code(组合数学)

    xiaoxiao2021-03-26  24

    POJ 1850 code

    题目大意

    将字母和单词(全部小写并且按照字典序递增)按照字典序编号,比如 a-1 b-2 … z-26 ab-27 … az-51 … 给你一个字母或单词,问你它的编号

    分析

    以树状的结构来分析这道题会比较直观。 按照树的节点依次编号,每个字母或单词就落在一个节点上。要求一个单词的编号,比较直接的想法是分别求出该 单词上一层的最大编号和该单词在当前层中所处的位置。(根节点为第0层)

    下面分别进行讨论

    上一层的最大编号

    某一层的节点数是有规律可循的,而某一层的最大编号则是该层及之前所有层的节点数之和。

    令第i层的节点数为 Fi

    数学公式 Cmn=n1i=1Cm1i(1)

    F1 =26

    F2 =25+24+…+1= 25i=1i = C226 = C125+C124+...+C11 = 25i=1C1i

    F3 = 24i=1(ij=1C1j) = 24i=1C2i+1 = C326

    同理 F4 = C426 (求出前三个第四个也可以猜出来了)

    某一层k的最大编号则是 F1+F2+...+Fk ,找不到化简公式也可以直接用循环直接求出来。

    当前层中所处的位置

    求在当前层中所处的位置则要复杂一些了,看似不是规则的树状结构,但仔细观察后发现这棵树是具有自相似性的,比如以编号为1的节点为根节点的子树具有和原树一样的性质。基于这一条启发式信息,问题就可以求解了.

    代码

    #include<cstdio> #include<iostream> #include<cmath> #include<cstring> #include<cstdlib> #include<queue> using namespace std; const int INF=999999999; #define LL long long int char s[11];//输入 int bj[30];//标记之前某个字母是否被访问过 LL f[27][11];//f[i][j]表示对于根节点有i个分支第j层的节点数, 根节点是第0层 LL A[11]; int Find_loc(char c0,char c,int bj[])//在某些字母被标记的情况下询问字母c处于字母树中的第几个分支,c0是前一个字母 { int cnt=0; for(int i=(int)c0-96+1;i<=26;i++) { if(bj[i]==0)cnt++; if(i==(int)c-96){return cnt;} } } void Get_A() { LL t=1; for(int i=1;i<=10;i++){t=t*i;A[i]=t;} } void Get_f() { LL x; for(int i=1;i<=26;i++) { f[i][0]=1; x=1;//保存当前层的节点数 for(int j=1;j<=min(10,i);j++) { x=(i-j+1)*x; f[i][j]=x/A[j]; } } } bool Check(char s[]) { int lenth=strlen(s); if(lenth>10)return 0; for(int i=1;i<lenth;i++)if(s[i]<s[i-1])return 0; return 1; } void Work() { LL ans=0; int lenth=strlen(s); if(Check(s)==0){cout<<0<<endl;return ;} int loc; LL node=26;//保存当前的节点的父亲的分支数 for(int i=1;i<=lenth-1;i++)ans+=f[26][i];//求上一层的最大编号 //cout<<"before_ans: "<<ans<<endl; for(int i=0;i<lenth;i++) { if(i==0)loc=(int)s[i]-96; else loc=Find_loc(s[i-1],s[i],bj); bj[(int)s[i]-96]=1; for(int j=1;j<loc;j++)ans+=f[node-j][lenth-i-1]; node=node-loc;//更新node } ans+=1; cout<<ans<<endl; } int main() { Get_A(); Get_f(); while(scanf("%s",s)!=EOF) { Work(); } }
    转载请注明原文地址: https://ju.6miu.com/read-662339.html

    最新回复(0)