题目要求:
给出2-8个坐标,代表八台电脑,找出把这些电脑连成一串的最小的线长。最后要加上16*(N-1),预留的线长。
解题思路:
8!不是很大,所以可以枚举,求出所有顺序的长度,如果<min就更新min,用ans记录电脑的位置关系和距离关系。最后输出ans数组即可。用了next_permutation()求下一个排列进行的枚举。
细节注意:
输出很多,注意输出的细节问题,WA一次因为输出语句落了最后的'.'。
AC代码:
//#define Local
#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>
#include <cstdio>
#include <queue>
#include <stack>
#include <algorithm>
#include <cmath>
using namespace std;
struct Coor
{
int x;
int y;
};
struct Dis
{
int x;
int y;
double s;
};
double cal_dis(Coor a, Coor b)
{
return sqrt((a.x - b.x) * ( a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int main()
{
#ifdef Local
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
#endif
int i = 0, j = 0, n = 0, vis[10], t = 0;
Coor coor[10] = {0, 0};
Dis dis[10] = {0, 0, 0}, ans[10] = {0, 0, 0};
while (cin >> n && n)
{
for (i = 0; i < n; i++)
{
cin >> coor[i].x >> coor[i].y;
vis[i] = i;
}
double min = 1 << 30; //新学到的
do
{
double sum = 0, tempdis = 0;
for (i = 0; i < n-1; i++)//n-1
{
tempdis = cal_dis(coor[vis[i]], coor[vis[i+1]]);
dis[i].x = coor[vis[i]].x;
dis[i].y = coor[vis[i]].y;
dis[i].s = tempdis;
sum += tempdis;
}
dis[i].x = coor[vis[i]].x;//为了输出最后的坐标,但此时i已经加1,不需要vis[i+1]了
dis[i].y = coor[vis[i]].y;
if (sum < min)
{
min = sum;
for (i = 0; i < n; i++)
{
ans[i].x = dis[i].x;
ans[i].y = dis[i].y;
ans[i].s = dis[i].s + 16;
}
}
}while (next_permutation(vis, vis+n));
min = min + 16 * (n-1);
cout << "**********************************************************" << endl;
cout << "Network #" << ++t << endl;
for (i = 0; i < n-1; i++)
{
printf("Cable requirement to connect (%d,%d) to (%d,%d) is %.2lf feet.\n", ans[i].x, ans[i].y, ans[i+1].x, ans[i+1].y, ans[i].s);
}
cout << setprecision(2) << fixed << "Number of feet of cable required is " << min << '.' << endl;
}
}