zoj 2207 || poj 2038 Team Rankings(= =)

看题目看了半个小时才明白 = =。英语水平啊。。。
ABCDE中两两相对位置共有4+3+2+1 = 10种。
两个字符串比较,相对位置不同的存下,比如 ABCDE 和 ACBDE,相对位置就BC不一样,所以相差1。1就是value。
给你n的串,求出一个ABCDE的排列,使得得出的这个排列跟这n个串的相对位置差累和最小。
开始按自己想法,把位置记录下,排下序完事了 = =。再单独算value,算value用得很麻烦的方法。结果样例过了,但是是WA。呃。
自己的想法没有得到证明是不能乱用的!!!
搜题解。看人家题目就知道,用的枚举。我去啊。。。。不过也就120种排列。好吧。那枚举吧。
用DFS把120种排列列出来,然后记录每个字母的下标,然后与输入的n个字符串的下标的相对位置进行对比。
时间复杂度是O(5! + 120*n*5*5)。0ms。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> typedef struct NODE{ char str[10]; int pos[5]; }NODE; NODE arr[121];//存枚举出来的字符串 NODE brr[101];//存输入的字符串 int visit[5]; int cou,d; char temp[5]; void DFS() //深搜,枚举出来120种情况。。。 { int i; if( d == 5 ) { strcpy(arr[cou].str,temp); cou++; return ; } for(i=0; i<5; i++) if( !visit[i] ) { temp[d] = i + 'A'; visit[i] = 1; d++; DFS(); d--; visit[i] = 0; } } void init() { memset(visit,0,sizeof(visit)); cou = d = 0; } char str[110][7]; int main() { int n,i,k,sum,j,p,tmp,max,tempi; init(); DFS(); while( scanf("%d",&n)!=EOF && n ) { sum = 0; for(i=0; i<n; i++) scanf("%s",brr[i].str); for(i=0; i<cou; i++) //存每个字符的位置 { for(k=0; k<5; k++) arr[i].pos[arr[i].str[k]-'A'] = k; } for(i=0; i<n; i++) //同上 { for(k=0; k<5; k++) brr[i].pos[brr[i].str[k]-'A'] = k; } max = INT_MAX,tempi; for(i=0; i<cou; i++) { sum = 0; for(k=0; k<n; k++) { tmp = 0; for(j=0; j<5; j++)// 比较两个字符的相对位置是否一样。一样的话差值相乘肯定大于0的。 for(p=j+1; p<5; p++) if( ( arr[i].pos[j] - arr[i].pos[p] ) * ( brr[k].pos[j]-brr[k].pos[p] ) < 0 ) tmp++; sum += tmp; } if( sum < max )//保存最小的value以及标号 { max = sum; tempi = i; } } printf("%s is the median ranking with value %d./n",arr[tempi].str,max); } return 0; }  

你可能感兴趣的:(struct)