POJ1850 Code【全排列】

题目链接:

http://poj.org/problem?id=1850

题目大意:

给你一个字符串str,输出str在字典序全排列中的位置(从小到大排列)。

解题思路:

参考博文:http://www.cnblogs.com/lyy289065406/archive/2011/07/31/2122760.html

先判断str是不是升序序列,如果是升序序列,则为字典序的第1个,输出1。

不符合第一步的话,则分为两步计算str的字典序位置。

先计算比 str 的长度少的字符串总个数。

再计算长度和 str 一样,比 str 字典序的字符串的个数。

先来看第一步:

长度为 1 的字符串个数为 C(26,1)。

长度为 2 的字符串个数为 C(26,2)。

……

长度为 2 的字符串个数为 C(26,2)。

再来看第二步:

对于 str 的每一位 str[i] 和左边相邻的 str[i-1],如果str[i] > str[i-1],说明当前位置str[i]
至少

比前一位的 str[i-1] 大。

答案 ans 要加上用比 str[i]大的字母构成长度为 len-1-i 的字符串个数,即 C[26-ch][len-1-i]。

ch 从 str[i] 到 str[i-1] + 1。

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

int C[27][27];
void ZuHe()
{
    C[0][0] = C[1][0] = C[1][1] = 1;
    for(int i = 2; i <= 26; ++i)
    {
        C[i][0] = C[i][i] = 1;
        for(int j = 1; j < i; ++j)
            C[i][j] = C[i-1][j] + C[i-1][j-1];
    }
}

char str[20];

int main()
{
    ZuHe();
    while(~scanf("%s",str))
    {
        int ans = 0;

        int len = strlen(str);
        bool falg = true;
        for(int i = 1; i < len; ++i)
        {
            if(str[i] <= str[i-1])
            {
                falg = false;
                break;
            }
        }
        if( !falg )
        {
            printf("0\n");
            continue;
        }

        int Time = len-1;
        while(Time)
        {
            ans += C[26][Time];
            Time--;
        }

        int ch,ch1;
        for(int i = 0; i < len; ++i)
        {
            ch = str[i] - 'a';
            if(i == 0)
                ch1 = 0;
            else
                ch1 = str[i-1] - 'a' + 1;
            while(ch > ch1)
            {
                ans += C[26-ch][len-1-i];
                ch--;
            }
        }
        ans++;
        printf("%d\n",ans);
    }

    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-06 13:43:53

POJ1850 Code【全排列】的相关文章

POJ1850 Code 【排列组合】

还不算是难题(嘿嘿,因为我做出来了) 很简单,找到相应的方程式解就是了(中间也犯了一个很2的错误,把9+10+11+...+99写成(1+90)*90/2,改过来后就好了) 不多说,code is below #include <iostream> #include <cstdio> #include <cstring> using namespace std; int combi(int a,int b) { int sum=1; int j=1; for(int i

poj1496 Word Index / poj1850 Code(组合数学)

poj1850 Code 题意:输出若干个给定的字符串($length<=10$)在字典序中的位置,字符串中的字母必须严格递增. 读取到非法字符串时,输出“0”,终止程序.(poj1496:继续读取) 我们分成2种情况讨论字典序小于给定字符串的字符串个数 1.长度比给定字符串小 其实长度为$i$的字符串的个数就是$C(26,i)$ 因为我们随机选取$i$个字符后,从小到大依次取出,是可以保证字符串是有序的. 2.长度等于给定字符串 我们枚举每一位,计算从该位开始小于给定字符串的个数,同样可以用组

POJ1850——Code(组合数学)

Code DescriptionTransmitting and memorizing information is a task that requires different coding systems for the best use of the available space. A well known system is that one where a number is associated to a character sequence. It is considered t

poj1850 Code【组合数学】By cellur925

题意: * 按照字典序的顺序从小写字母 a 开始按顺序给出序列 (序列中都为升序字符串)* a - 1* b - 2* ...* z - 26* ab - 27* ...* az - 51* bc - 52* ...* vwxyz - 83681* 输入字符串由小写字母 a-z 组成字符串为升序,根据字符串输出在字典里的序列号为多少. 很容易地我们可以想到,设输入的字符串长度为len,我们可以用组合数求出所有小于len长度的字符串数量,(感觉这一步很好理解,反而许多题解给出了详细的证明?). 然

poj1850(Code)

题目地址:Code 题目大意: 按照字典序的顺序从小写字母a开始按顺序给出序列 a - 1     b - 2     ...     z - 26     ab - 27     ...     az - 51     bc - 52     ...     vwxyz - 83681     ... 输入字符串由小写字母a-z组成字符串为升序,根据字符串输出在字典里的序列号为多少. 解题思路: 排列组合,记住公式: 先看字符的长度一个字符的时候是26为C(26,1),两个字符的时候分别从以a

POJ1850 Code(组合+康托展开)

题目问一个合法字符串的字典序是第几个,合法的字符串是指里面的字符严格递增. 先判断合不合法,然后用类似康托展开的过程去求.大概过程就是用组合数算出某长度某前缀有几个,累加起来. 真难一遍写对.. 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 bool islegal(char *s){ 5 for(int i=1; s[i]; ++i){ 6 if(s[i]<=s[i-1]) return 0;

CODE[VS] 1294 全排列

1294 全排列 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 给出一个n, 请输出n的所有全排列 输入描述 Input Description 读入仅一个整数n   (1<=n<=10) 输出描述 Output Description 一共n!行,每行n个用空格隔开的数,表示n的一个全排列.并且按全排列的字典序输出. 样例输入 Sample Input 3 样例输出 Sample Output 1 2

题目1120:全排列

题目描述: 给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列.我们假设对于小写字母有'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中的字母已经按照从小到大的顺序排列. 输入: 输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间. 输出: 输出这个字符串的所有排列方式,每行一个排列.要求字母序比较小的排列在前面.字母序如下定义:已知S = s1s2...sk , T = t1t2...tk,则S < T 等价

组合数学 + STL --- 利用STL生成全排列

Ignatius and the Princess II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4730    Accepted Submission(s): 2840 Problem Description Now our hero finds the door to the BEelzebub feng5166. He op