蓝桥杯 2014 4 排列序数

如果用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
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms

##Algorithm
以abcd四个字母为例
光看第一个 显然是6个一组
axxx bxxx cxxx dxxx
看第二个 发现是2个一组

abxx acxx adxx
显然就是以 n! 为组的单位
不过要把a除去
这样就可以得到算法

每次算出当前字符在剩下字符集合里面的排名,然后乘上N!, 并且把这个在集合里面删除
注意这个集合是有序的,而STL set可以实现

##Code

#include 
using namespace std;
int main()
{
	string s;
	getline(cin, s);
	set st;
	for (int i = 0; i < s.size(); i++) {
		st.insert('a' + i);
	}
	vector x;
	x.push_back(1);
	for (int i = 1; i <= s.size(); i++) {
		x.push_back(i * x.back());
	}
	int ans = 0;
	for (int i = 0; i < s.size(); i++) {
		int cnt = 0;
		for (char e : st) {
			if (e == s[i]) {
				st.erase(e);
				break;
			}
			cnt++;
		}
		//cout << cnt << endl;
		//cout << x[s.size() - i - 1] << endl;
		ans += cnt * x[s.size() - i - 1];
	}
	cout << ans << endl;
}

##Offical Test Data

  • input
abcdefg
abdefgc
gabdefc
abdefgchij
iabdefgchj
  • output

0
33
4329
5904
2903910

你可能感兴趣的:(蓝桥杯 2014 4 排列序数)