时间限制:1.0s 内存限制:256.0MB
试题来源:蓝桥杯决赛2014 C++本科A组
问题描述
如果用a b c d这4个字母组成一个串,有4!=24种,如果把它们排个序,每个串都对应一个序号:
abcd 0
abdc 1
acbd 2
acdb 3
adbc 4
adcb 5
bacd 6
badc 7
bcad 8
bcda 9
bdac 10
bdca 11
cabd 12
cadb 13
cbad 14
cbda 15
cdab 16
cdba 17
...
现在有不多于10个两两不同的小写字母,给出它们组成的串,你能求出该串在所有排列中的序号吗?
输入格式
一行,一个串。
输出格式
一行,一个整数,表示该串在其字母所有排列生成的串中的序号。注意:最小的序号是0。
样例输入
bdca
样例输出
11
样例输入
cedab
样例输出
70
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string str;
cin >> str;
int n = str.size();
int ans = 0;
int fact[11] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800};
// 计算排列的序号
for (int i = 0; i < n; i++) {
int cnt = 0;
for (int j = i + 1; j < n; j++) {
if (str[j] < str[i]) {
cnt++;
}
}
ans += cnt * fact[n - i - 1];
}
cout << ans << endl;
return 0;
}
-
代码逻辑:
该代码用于计算给定字符串的所有排列的序号。排列的序号是该排列在所有可能排列中的顺序。例如,字符串 “abc” 的所有排列为 "abc", "acb", "bac", "bca", "cab", "cba",它们的序号分别为 1、2、3、4、5、6。
代码的具体逻辑如下:
-
首先获取输入字符串
str
。 -
计算字符串的长度
n
。 -
定义一个变量
ans
初始化为 0,用于存储所有排列的序号之和。 -
定义一个数组
fact
来存储 1 到 10 的阶乘值,因为排列的序号可能很大。 -
遍历字符串
str
中的每个字符 `str[i]:-
初始化一个计数器
cnt
为 0,用于计算在字符str[i]
右侧有多少个较小的字符。 -
遍历字符串
str
中的每个字符str[j]
,其中 `j > i:- 如果
str[j] < str[i]
,则cnt
加 1。
- 如果
-
将
cnt
乘以fact[n - i - 1]
,并加到ans
中。这表示在str[i]
右侧所有较小字符构成的排列的数量。
-
-
最终返回
ans
的值。
代码问题:
代码中没有明显的错误。但需要注意的是,该代码只适用于较短的字符串。对于较长的字符串,
ans
的值可能会溢出。为了解决这个问题,可以在计算ans
时使用高精度整数库。 -