题目链接:UVa 140 - Bandwidth
这题目放在书上回溯那块,我就直接往回溯那块想,但是这不知道怎么做到字典序,感觉就是做到了也很麻烦。
在网上搜了搜题解,看见好多人都用next_permutation做到的,看起来也没有超时。当然用这个函数做到字典序就比较简单了。
开始WA了几次,后来发现是char数组没有开够,开成26了。改了就AC了,0.025s。
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX_N = 26 + 1;
int G[MAX_N][MAX_N];
int c_to_i[MAX_N];
char c[1000];
int arr1[MAX_N];
int arr2[MAX_N];
int _min;
int main()
{
while(gets(c) && strcmp(c,"#"))
{
memset(G,0,sizeof(G));
memset(c_to_i,0,sizeof(c_to_i));
_min = MAX_N;
int len = strlen(c);
for(int i = 0;i < len;i++)
{
if(c[i] == ':')
{
int j = i - 1;
i++;
for(;i < len && c[i] != ';';i++)
{
G[c[i] - 'A'][c[j]-'A'] = G[c[j] - 'A'][c[i]-'A'] = 1;
c_to_i[c[i] - 'A'] = 1;
}
}
else
{
c_to_i[c[i] - 'A'] = 1;
}
}
int cnt = 0;
for(int k = 0;k < 26;k++)
{
if(c_to_i[k])
arr1[cnt++] = k;//字典序
}
do
{
int _max = 0;
for(int m = 0;m < cnt;m++)
{
for(int n = m + 1;n < cnt;n++)
{
if(G[arr1[m]][arr1[n]])
{
int temp = abs(m - n);
if(temp > _max)
_max = temp;
}
}
if(_max > _min)
break;
}
if(_min > _max)
{
_min = _max;
memcpy(arr2,arr1,sizeof(arr1));
}
}while(next_permutation(arr1,arr1+cnt));
for(int p = 0;p < cnt;p++)
cout<<char(arr2[p] + 'A')<<" ";
cout<<"-> "<<_min<<endl;
}
return 0;
}