采用的是枚举法,同时在判断的时候注意优化:如果当前计算出来的距离值已经比之前记录的最小距离值大,那么后续的计算就不需要进行了,具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
using namespace std;
int main(){
string s;
while (getline(cin, s)){
if (s == "#") break;
string s2 = "";
for (int i = 0; i < s.size(); i++){
if (s[i] != ' ') s2 += s[i];
}
s = s2;
map<char, int> ch2int;
map<int, char> int2ch;
int amount = 0;
for (char start = 'A'; start <= 'Z'; start++){
if (s.find(start) != string::npos){
ch2int[start] = amount;
int2ch[amount] = start;
amount++;
}
}
int* result = new int[amount];
int* temp = new int[amount];
for (int i = 0; i < amount; i++) temp[i] = i;
vector<int> head;
vector<int> tail;
for (int i = 0; i < s.size(); i++){
int first = ch2int[s[i]];
i += 2;
while (i < s.size() && s[i] != ';'){
int second = ch2int[s[i]];
head.push_back(first);
tail.push_back(second);
i++;
}
}
int *pos = new int[amount];
int ans = 10000000;
do{
int ans_t = 0;
for (int i = 0; i < amount; i++) pos[temp[i]] = i;
for (int i = 0; i < head.size(); i++){
ans_t = max(ans_t, abs(pos[head[i]] - pos[tail[i]]));
if (ans_t >= ans) break;
}
if (ans_t < ans){
ans = ans_t;
for (int i = 0; i < amount; i++) result[i] = temp[i];
}
} while (next_permutation(temp,temp+amount));
for (int i = 0; i < amount; i++){
cout << int2ch[result[i]] << ' ';
}
cout << "-> " << ans << endl;
}
return 0;
}