How big is it? (Computational ry + DFS)

Source: Internet
Author: User
Tags cmath

It can be said that this question involves many knowledge points and is a good question.

First, this question involves the knowledge of computational ry, finding the horizontal distance between the coordinates of the center and then finding the coordinates of the center. Second, it is easy to think of DFS because the data of this question is not big; the last question involves a full arrangement! In theory, this question can also be trimmed, and the steps are not very troublesome, but it can be done without pruning!

Next, let's talk about my initial idea. This idea is very troublesome. Finally, WA, simply put, is to judge from the right to the left, one tangent to the circle, calculate the coordinates, and then assume the coordinates, then proceed to the left side to check whether there is any circle that has an intersection with it. This idea is very troublesome. When I find the length after self, I also find the error. In fact, finding the leftmost coordinate and rightmost coordinate is the length, while I take the rightmost coordinate as the length. Although I have done some processing on the coordinate superborder, it is also a problem. I feel like!

After talking about the practice of AC, the boss told me this practice, and the operation is simple, and the code is also very streamlined. First, in a certain position, we must place the circle in the enumerated circle. We only need to determine the coordinates of the center to ensure that the circle is at least tangent to a circle, and will not interwork with other circles. Then, let me start the circle on the left of the circle that has been placed, let the current circle be tangent to these circles once, and find the coordinates that are tangent to each circle, find the value of X on the rightmost side, which is the position that can be placed currently. Of course, the value Y is the radius of the current circle. Secondly, we need to explain why this is correct. First, we need to ensure the minimum length of the same arrangement with the current arrangement, so we have to be tangent to the left circle. There is nothing to say about it. So why should we select the largest X coordinate? Think about all the X coordinates, are tangent to a circle, so for example, there are a total of 8 circles, put 3rd as the position, find the abscissa tangent to the first circle is 1, the abscissa of the second tangent circle is 2, so the tangent represents that it is just not intersecting. If we select the abscissa of 1, place the circle in this position, then this circle will inevitably intersect with the second circle. Therefore, you must select the rightmost of all the obtained coordinates. Another common mistake is to find only the coordinates tangent to the previous circle. In this case, if the second to last circle is very large, the current circle and the second to last circle cannot be overlapped, and so on, the last and third circles may be very large .....

The following lists some special situations of the circle position:

The first graph indicates that the circle may be intersecting with any previous circle. The second graph indicates that only the tangent to the last circle is incorrect.

Also note that length

Code without pruning:

#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>using namespace std;#define eps 1e-9const int N = 10;const double INF = 100000000.0;int T, n;int id[N];bool vis[N];double r[N], x[N], y[N], ans;void dfs( int now ) {    if (now == n) {       double lx = x[0], rx = x[0], tmp;       for ( int i = 0; i < n; ++i ) {       //cout << x[i] << " ";           lx = min( x[i]-r[id[i]], lx );           rx = max( x[i]+r[id[i]], rx );       }       //cout << endl << lx << ' ' << rx << endl;       tmp = rx - lx;       if ( tmp + eps < ans ) ans = tmp;    }    for ( int i = 0; i < n; ++i )         if ( !vis[i] ) {            double mx = x[0], my = r[i];            for ( int j = 0; j < now; ++j ) {                double rj = r[id[j]], xx;                xx = sqrt((rj+r[i])*(rj+r[i])-(rj-r[i])*(rj-r[i])) + x[j];                mx = max ( xx, mx );            }            x[now] = mx, y[now] = r[i], id[now] = i;            vis[i] = true;            dfs( now+1 );            vis[i] = false;        }}int main(){    scanf("%d", &T);    while ( T-- ) {        scanf("%d", &n);        for ( int i = 0; i < n; ++i ) scanf("%lf", &r[i]);        ans = INF;        memset( vis, 0, sizeof(vis) );        for ( int i = 0; i < n; ++i ) {            int cnt = 0;            vis[i] = true;            id[cnt] = i;            x[cnt] = y[cnt] = r[i];            dfs( cnt+1 );        //cout << "...................."<< endl;            vis[i] = false;        }        printf("%.3lf\n", ans);    }}

Code for pruning (if the current length is found to be greater than the specified length, it is returned ):

#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>using namespace std;#define eps 1e-9const int N = 10;const double INF = 100000000.0;int T, n;int id[N];bool vis[N];double r[N], x[N], y[N], ans;void dfs( int now, double tmp ) {    if (now == n) {       //double lx = x[0], rx = x[0], tmp;       /*for ( int i = 0; i < n; ++i ) {       //cout << x[i] << " ";           lx = min( x[i]-r[id[i]], lx );           rx = max( x[i]+r[id[i]], rx );       }       //cout << endl << lx << ' ' << rx << endl;       tmp = rx - lx;*/       if ( tmp + eps < ans ) ans = tmp;       return;    }    if ( tmp > ans + eps ) return;    for ( int i = 0; i < n; ++i )         if ( !vis[i] ) {            double mx = x[0], my = r[i], lx = x[0], rx = x[0];            for ( int j = 0; j < now; ++j ) {                double rj = r[id[j]], xx;                xx = sqrt((rj+r[i])*(rj+r[i])-(rj-r[i])*(rj-r[i])) + x[j];                mx = max ( xx, mx );                lx = min( x[j]-r[id[j]], lx );                rx = max( x[j]+r[id[j]], rx );            }            lx = min( mx-r[i], lx );            rx = max( mx+r[i], rx );            x[now] = mx, y[now] = r[i], id[now] = i;            vis[i] = true;            dfs( now+1, rx-lx );            vis[i] = false;        }}int main(){    scanf("%d", &T);    while ( T-- ) {        scanf("%d", &n);        for ( int i = 0; i < n; ++i ) scanf("%lf", &r[i]);        ans = INF;        memset( vis, 0, sizeof(vis) );        for ( int i = 0; i < n; ++i ) {            int cnt = 0;            vis[i] = true;            id[cnt] = i;            x[cnt] = y[cnt] = r[i];            dfs( cnt+1, r[i]*2 );        //cout << "...................."<< endl;            vis[i] = false;        }        printf("%.3lf\n", ans);    }}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.