全排列,统计记录每个排列中“带宽”最大的值,最后输出所有最大值中最小的那个。
代码如下:
#include <iostream> #include <algorithm> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> using namespace std; int cct, ahl[27], map[27][27]; int save[9], node[9]; char a[500]; int main() { #ifdef test freopen("sample.txt", "r", stdin); #endif int len, c, _max; while(gets(a)) { if(!strcmp(a, "#")) break; _max =10; cct = 0; len = strlen(a); memset(map, 0, sizeof(map)); memset(ahl, 0, sizeof(ahl)); for(int i = 0, flag = 0; i < len; i++) { if(a[i] >= 'A' && a[i] <= 'Z') ahl[a[i] - 'A'] = 1; if(a[i] == ':') { c = a[i - 1] - 'A'; flag = 1; } else if(flag && a[i] >= 'A' && a[i] <= 'Z') map[a[i] - 'A'][c] = map[c][a[i] - 'A'] = 1; else if(a[i] == ';') flag = 0; } for(int i = 0; i < 26; i++) if(ahl[i]) node[cct++] = i; do { int num = 0; for(int i = 0; i < cct; i++) for(int j = i + 1; j < cct; j++) if(map[node[i]][node[j]]) if(abs(i - j) > num) num = abs(i - j); if(_max > num) { _max = num; memcpy(save, node, sizeof(node)); } } while(next_permutation(node, node + cct)); for(int i = 0; i < cct; i++) printf("%c ", save[i] + 'A'); printf("-> %d\n", _max); } return 0; }
剪枝版:
#include <iostream> #include <algorithm> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> using namespace std; int cct, ahl[27], map[27][27]; int save[9], node[9]; char a[500]; int main() { #ifdef test freopen("sample.txt", "r", stdin); #endif int len, c, _max; while(gets(a)) { if(!strcmp(a, "#")) break; _max =10; cct = 0; len = strlen(a); memset(map, 0, sizeof(map)); memset(ahl, 0, sizeof(ahl)); for(int i = 0, flag = 0; i < len; i++) { if(a[i] >= 'A' && a[i] <= 'Z') ahl[a[i] - 'A'] = 1; if(a[i] == ':') { c = a[i - 1] - 'A'; flag = 1; } else if(flag && a[i] >= 'A' && a[i] <= 'Z') map[a[i] - 'A'][c] = map[c][a[i] - 'A'] = 1; else if(a[i] == ';') flag = 0; } for(int i = 0; i < 26; i++) if(ahl[i]) node[cct++] = i; do { int num = 0; for(int i = 0; i < cct; i++) { for(int j = i + 1; j < cct; j++) { if(map[node[i]][node[j]]) if(abs(i - j) > num) num = abs(i - j); } if(num > _max) // 剪枝,num>_max时,直接跳出不用继续往下判断 break; } if(_max > num) { _max = num; memcpy(save, node, sizeof(node)); } } while(next_permutation(node, node + cct)); for(int i = 0; i < cct; i++) printf("%c ", save[i] + 'A'); printf("-> %d\n", _max); } return 0; }