题目大意:给你n台电脑,每条线可以连着两台电脑,求将所有电脑连起来最短需要多长的线(一条折线),每段线要另外再加16。
解题思路:全排列,取其中最短的情况即可。由1到n的全排列演变为下标就可以了。
全排列代码:
#include <iostream>
#include <cstring>
using namespace std;
int n, vis[1005], num[1005];
void dfs(int d)
{
if (d >= n){
for (int i=0; i<n; i++)
printf("%d ", num[i]);
printf("\n");
}
else{
for (int i=0; i<n; i++)
if (!vis[i]){
vis[i] = 1;
num[d] = i+1;
dfs(d+1);
vis[i] = 0;
}
}
}
int main()
{
while (scanf("%d", &n)!=EOF){
memset(vis, 0, sizeof(vis));
dfs(0);
}
return 0;
}
ac代码:
#include <iostream>
#include <math.h>
#include <cstring>
using namespace std;
struct node{
int a;
int b;
}no[10];
int n, cnt, num[10], vis[10], mi[10], count=1, temp2[10];
double sum, temp;
double dis(node a, node b)
{
double d;
d = sqrt(pow( (a.a-b.a),2 ) + pow( (a.b-b.b),2 ));
return d+16;
}
void dfs(int d)
{
if (d >= n){
temp = 0;
for (int i=0; i<n-1; i++){
temp += dis(no[num[i]], no[num[i+1]]);
temp2[i] = num[i], temp2[i+1] = num[i+1];
}
if (temp < sum || !sum){
sum = temp;
for (int i=0; i<n; i++)
mi[i] = temp2[i];
}
}
else{
for (int i=0; i<n; i++){
if (!vis[i]){
vis[i] = 1;
num[d] = i;
dfs(d+1);
vis[i] = 0;
}
}
}
}
int main()
{
while (scanf("%d", &n)!=EOF && n){
cnt = 1;
sum = 0;
memset(vis, 0, sizeof(vis));
for (int i=0; i<n; i++){
cnt *= i+1;
scanf("%d%d", &no[i].a, &no[i].b);
}
dfs(0);
printf("**********************************************************\n");
printf("Network #%d\n", count++);
for (int i=0; i<n-1; i++)
printf("Cable requirement to connect (%d,%d) to (%d,%d) is %.2lf feet.\n",
no[mi[i]].a, no[mi[i]].b, no[mi[i+1]].a, no[mi[i+1]].b, dis(no[mi[i]], no[mi[i+1]]));
printf("Number of feet of cable required is %.2lf.\n", sum);
}
return 0;
}