链接:http://acm.hust.edu.cn/vjudge/problem/19399分析:将结点字母用数字0~n-1表示,id[ch]将字符映射到对应的数字编号,letter将数字编号映射到对应的字符,用两个vector将每个结点的相邻结点编号存下来,然后枚举0~n-1位置上的结点编号,用pos记录每个结点编号所在的位置方便以后查找,然后就是遍历vector,第一个vector代表结点编号i,第二个vector代表结点i的相邻结点编号,找出最远距离,如果当前找到的最远距离已经大于或等于ans,则不能更优应剪枝,然后就是更新ans和bestP,直至枚举完0~n-1的所有排列。
1 #include <cstring> 2 #include <cstdio> 3 #include <vector> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn = 10; 9 int id[256], letter[maxn]; 10 11 int main() { 12 char input[1000]; 13 while (scanf("%s", input) == 1 && input[0] != ‘#‘) { 14 int n = 0; 15 for (char ch = ‘A‘; ch <= ‘Z‘; ch++) 16 if (strchr(input, ch) != NULL) { 17 id[ch] = n++; 18 letter[id[ch]] = ch; 19 } 20 vector<int> u, v; 21 int len = strlen(input); 22 for (int p = 0, q = 0; q < len; p++, q++) { 23 while (input[p] != ‘:‘) p++; 24 while (q < len && input[q] != ‘;‘) q++; 25 for (int i = p + 1; i < q; i++) { 26 u.push_back(id[input[p - 1]]); 27 v.push_back(id[input[i]]); 28 } 29 } 30 int pos[maxn], P[maxn], bestP[maxn], ans = n; 31 for (int i = 0; i < n; i++) P[i] = i; 32 do { 33 for (int i = 0; i < n; i++) pos[P[i]] = i; 34 int bandwidth = 0; 35 for (int i = 0; i < u.size(); i++) { 36 bandwidth = max(bandwidth, abs(pos[u[i]] - pos[v[i]])); 37 if (bandwidth >= ans) break; 38 } 39 if (bandwidth < ans) { 40 ans = bandwidth; 41 memcpy(bestP, P, sizeof(P)); 42 } 43 } while (next_permutation(P, P + n)); 44 for (int i = 0; i < n; i++) printf("%c ", letter[bestP[i]]); 45 printf("-> %d\n", ans); 46 } 47 return 0; 48 }
时间: 2024-12-14 02:19:47