圆排列问题
问题描述:
给定n个大小不等的圆 c1 c2 c3 c4 要将n个圆排进一个矩形框中,且要求底边相切。找出有最小长度的圆排列。
例如:当n=3,且所给的3个圆半径分别为1,1,2时,这3个圆的最小长度的圆排列 最小长度为2+4根号2.
// Circle.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
template<class Type>
class Circle
{
template<class Ty>
friend void CirclePerm(int, int*);
private:
Type Center(int);
void Backtrack(int t);
Type min,//最小长度
* x;//当前圆当圆心的距离
int * r;//当前排列
int n;
};
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
template<class Type>
Type Circle<Type>::Center(int t)
{
float temp = 0.0;
for (int i = 1; i < t; i++)
{
float value = x[i] + 2 * sqrt(r[t] * r[i]);
if (value > temp)
temp = value;
}
return temp;
}
template<class Type>
void Circle<Type>::Backtrack(int t)
{
if (t > n)
{
for (int i = 0; i <= n; i++)
std::cout << r[i] << "\t";
std::cout << std::endl;
if (x[t-1] + r[1]+r[t-1] < min)
min = x[t-1] + r[1]+ r[t - 1];
std::cout <<std::fixed<< min << std::endl;
}
else
{
for (int i = t; i <= n; i++)
{
swap(&r[t], &r[i]);
float centers = Center(t);
if (centers + r[t] + r[1] < min)
{
x[t] = centers;
Backtrack(t + 1);
}
swap(&r[t], &r[i]);
}
}
}
template<class Ty>
void CirclePerm(int n, int* r)
{
Circle<float> circle;
circle.r = r;
circle.x = new float[4];
circle.min = 10000;
circle.n = n;
circle.Backtrack(1);
}
int main()
{
int* r = new int[4];
r[0] = 0, r[1] = 1, r[2] = 1, r[3] = 2;
CirclePerm<float>(3, r);
return 0;
}