/*1006. Team Rankings
题目大意:给出n串由A B C D E组成的任意字符序列,求出与这n串序列
之间的差值最小的序列,并输出其差值.
求两串字符的差值规则:如 ABDCE, BACDE, ABCED and ACBDE, 则ABCDE
与他们的差值和为1 + 1 + 1 + 1 = 4. 因为如 ABDCE 和 ABCDE中两个字
符串的相对位置不同的对数只有一对,即DC 和CD 依次类推。。。
解题方法1: 利用N皇后的方法,让他们各种可能的序列。然后用该生成的
序列candidate与给出的n组序列ranking[i],分别求出差值并求和。
这里求差值的方法:使用map<char, int> ,先把candidate中各个字符(key)
与其所处的下标(value)映射起来。即如ABCDE对应的map为
{ (A,0), (B,1), (C,2), (D, 3), (E, 4)}
然后在遍历ranking[i]时, 如 ABDCE ,先从取第一位如A,然后与后面的
B、C、D、E在上述map中的相对位置比较
如果出现 map[charA] > map[charLast],即出现相对位置与map上的不用的,差值+1
解题方法2: 可以直接使用系统提供的函数求全排列,
next_permutation(str.begin(), str.begin()+偏移量) ,其生成的全排列就放在
str中
调用如下
do {
}while(next_permutation(str.begin(), str.begin()+偏移量)); //生成字符串
//ABCDE的所有排列,但是要求原始的字符串是从小到大排列开始,生成成功就返回true
*/
#include <iostream>
#include <stdlib.h>
#include <stack>
#include <algorithm>
#include <map>
using namespace std;
map<char, int> m;
int getDistance(string b)
{
int distance = 0;
for(int i=0; i<4; i++)
for(int j=i+1; j<5; j++)
if(m[b[i]] > m[b[j]])
distance++;
return distance;
}
int main()
{
int n=-1;
int sum;
string ranking[100];
while(cin >> n && n != 0)
{
for(int i=0; i<n; i++)
cin >> ranking[i];
//a[i]的值为列数,i为行数
int min = 99999;
string final;
string initStr = "ABCDE";
do
{
for(int i=0; i<initStr.length(); i++)
m[initStr[i]] = i;
sum =0;
for(int i=0; i<n; i++){
sum += getDistance(ranking[i]);
}
if(sum < min)
{
min = sum;
final = initStr;
}
}while(next_permutation(initStr.begin(), initStr.begin()+5));
cout << final << " is the median ranking with value " << min << "."<< endl;
}
system("pause");
return 0;
}