Sicily.1006. Team Rankings

/*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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值