sicily 1006. Team Rankings

//先用table[200]存储“ABCDE”到“EDCBA”所有的排列,计算每个的逆序数
//比如“CDEAB”,"CA"是逆序数,则标记num[64][2]=1,其中 64表示在全排列中的位置,而 2 的运算如下:
// e=table[i][j]-'A';f=table[i][k]-'A';     if(e>f)    num[i][e+f*5]=1;  
//在该例中,e=2;f=0;所以 e+f*5=2; 可以看出最大逆序值是"ED", e=4;f=3; 则e+f*5=19;
//故逆序值散落在 [1,19]范围内;
//接着输入 n 个字符串,同样地计算出逆序值来,于是对全排列逐一查找

#include
<iostream>
#include
<stdio.h>
#include
<algorithm>
#include
<cstring>
using namespace std;
char table[200][10],input[100][10];
int n,num[200][20],ans[100][20];
int main()
{
    
char ch[10]="ABCDE";
    
int e,f;
    
char *first=ch,*last=ch+5;
    
int rear=0;
    
do
    {
        strcpy(table[rear
++],ch);
    }
while(next_permutation(first,last));
    
for(int i=0;i<rear;++i)
    {
        
for(int j=0;j<5;++j)
            
for(int k=j+1;k<5;++k)
            {
                e
=table[i][j]-'A';f=table[i][k]-'A';
                
if(e>f)
                    num[i][e
+f*5]=1;
            }
    }

    
while(cin>>n&&n)
    {
        memset(ans,
0,sizeof(ans));
        
for(int i=0;i<n;++i)
            cin
>>input[i];
        
for(int i=0;i<n;++i)
        {
            
for(int j=0;j<5;++j)
                
for(int k=j+1;k<5;++k)
                {
                    e
=input[i][j]-'A';f=input[i][k]-'A';
                    
if(e>f)
                        ans[i][e
+f*5]=1;
                }
        }
        
int res=0x7fffffff,s;
        
char med[10];
        
for(int i=0;i<rear;++i)
        {
            s
=0;
            
for(int j=0;j<n;++j)
            {
                
for(int k=0;k<20;++k)
                    
if(num[i][k]!=ans[j][k])    //说明一个为 1,一个为 0 ;如果两个都为 1或 0 ,则不是逆序对 
                        s++;
            }
            
if(s<res)
            {
                res
=s;
                strcpy(med,table[i]);
            }
        }
        printf(
"%s is the median ranking with value %d.\n",med,res);
    }
    
return 0;
}

  

posted on 2011-07-04 18:31  sysu_mjc  阅读(397)  评论(0编辑  收藏  举报

导航