// How big is it? (How big is it ?) // PC/ultraviolet A IDs: 111308/10012, popularity: B, success rate: Low Level: 3 // verdict: accepted // submission date: 2011-11-05 // UV Run Time: 0.272 S // copyright (c) 2011, Qiu. Metaphysis # Yeah dot net // [solution] // traverse all possible rings by backtracking, calculate the width, and then obtain the minimum value as the result, when calculating the ring width, pay attention to some // details. # Include <iostream> # include <cstring> # include <iomanip> # include <cmath> using namespace STD; # define maxn 8 struct cycle {Double X, Y; double R ;}; double smallestwidth; // calculates the width of the ring arrangement in the specified sequence. Double calwidth (double radius [], int M, int used []) {double width = 0.0; cycle packedcycles [maxn]; // take the lower left corner of the box as the Cartesian coordinate system origin (0, 0), and calculate the coordinates of the center of the last placed ring. the abscissa plus its // radius is the width of the box. During calculation, we need to consider that the ring may be completely under a certain ring, but not beyond the radius of the larger circle // ring. Packedcycles [0] = (cycle) {radius [used [0], radius [used [0], radius [used [0]}; for (INT I = 1; I <m; I ++) {// the current position of the I ring. Assume that the ring is tangent to the ring numbered 0-(I-1), and check whether there is any conflict. If there is no conflict, the ring I is tangent to the ring, then, the coordinates of the center can be calculated. For (Int J = I-1; j> = 0; j --) {// The Center coordinate of the ring. Double tmpx = packedcycles [J]. X, tmpy = radius [used [I]; // the difference between the center distance and the ordinate. Double centerdist = packedcycles [J]. R + radius [used [I]; double ydiff = FABS (packedcycles [J]. r-radius [used [I]); // The Difference Between the x-axis is calculated by the hook theorem. Note that in special cases, if the first ring is relatively small, // The Ring following it may go beyond the left boundary, so its abscissa is at least its radius. Tmpx + = SQRT (POW (centerdist, 2)-Pow (ydiff, 2); If (tmpx <radius [used [I]) tmpx = radius [used [I]; // check whether there is a conflict, that is, whether the distance between the center of the two is greater than the sum of the radius of the two rings. Bool successed = true; For (int K = 0; k <I; k ++) if (K! = J) {centerdist = POW (tmpx-packedcycles [K]. x, 2); centerdist + = POW (tmpy-packedcycles [K]. y, 2); centerdist = SQRT (centerdist); If (centerdist <(packedcycles [K]. R + radius [used [I]) {successed = false; break ;}// no conflict exists in the ring. If (successed) {packedcycles [I] = (cycle) {tmpx, tmpy, radius [used [I]}; break ;}// return the width of the box, take the coordinates of the center plus the maximum radius, because the last circle is not necessarily the rightmost. Double maxright = 0.0; For (INT I = 0; I <m; I ++) maxright = max (maxright, packedcycles [I]. X + packedcycles [I]. r); Return maxright;} // traverses all possible rings. Void backtrack (double radius [], int M, int C, int used [], bool unused []) {If (C = m) smallestwidth = min (smallestwidth, calwidth (radius, M, used); else {for (INT I = 0; I <m; I ++) if (unused [I]) {unused [I] = false; used [c] = I; backtrack (radius, M, C + 1, used, unused); unused [I] = true ;}}} int main (int ac, char * AV []) {INT cases, M; double radius [maxn]; int used [maxn]; bool unused [maxn]; cout. precision (3); cout. SETF (IOs: Fixed | IOs: showpoint); CIN> cases; while (cases --) {CIN> m; smallestwidth = 0.0; For (INT I = 0; I <m; I ++) {CIN> radius [I]; smallestwidth + = radius [I];} smallestwidth * = 2.0; memset (unused, true, sizeof (unused); backtrack (radius, M, 0, used, unused); cout <smallestwidth <Endl;} return 0 ;}