【a503】圆排列问题

Time Limit: 1 second
Memory Limit: 32 MB

【问题描述】

给定n个大小不等的圆c1,c2,...., cn,现要将这n个圆排列进一个矩形框中,且要求各圆与矩形框的底边相切。圆排列问题要求从n个圆的所有排列中找出有最小长度的圆排列。例如:当n=3时,且所给的3个圆的半径分别为1,1,2时,这3个圆的最小长度的圆排列如下图所示,其最小长度为7.6569

这里写图片描述
【输入格式】

共两行,第一行为圆的个数,第二行为每个圆的半径。

【输出格式】

仅有一行,圆排列的最小长度(保留四位小数)。

【输入样例】

1
4

【输出样例】

8.0000

【题目链接】:http://noi.qz5z.com/viewtask.asp?id=a503

【题解】

把所有的排列都搞出来即可;
用勾股定理算出相邻两个圆圆心的平行距离;
最后把第一个圆和最后一个圆的半径加上去;

【完整代码】

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

void rel(LL &r)
{
    r = 0;
    char t = getchar();
    while (!isdigit(t) && t!='-') t = getchar();
    LL sign = 1;
    if (t == '-')sign = -1;
    while (!isdigit(t)) t = getchar();
    while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
    r = r*sign;
}

void rei(int &r)
{
    r = 0;
    char t = getchar();
    while (!isdigit(t)&&t!='-') t = getchar();
    int sign = 1;
    if (t == '-')sign = -1;
    while (!isdigit(t)) t = getchar();
    while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
    r = r*sign;
}

const int MAXN = 100;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);

int n,xl[MAXN];
double a[MAXN];
bool bo[MAXN];
double ans=21e8;

double sqr(double x)
{
    return x*x;
}

void sear_ch(int now)
{
    if (now==n+1)
    {
        double temp = 0;
        rep1(i,2,n)
        {
            double h = abs(a[xl[i]]-a[xl[i-1]]);
            double r1pr2=a[xl[i]]+a[xl[i-1]];
            temp+=sqrt(sqr(r1pr2)-sqr(h));
        }
        temp+=a[xl[1]]+a[xl[n]];
        ans = min(ans,temp);
        return;
    }
    rep1(i,1,n)
    if (!bo[i])
    {
        bo[i] = true;
        xl[now]=i;
        sear_ch(now+1);
        bo[i] = false;
    }
}

int main()
{
    //freopen("F:\rush.txt","r",stdin);
    memset(bo,false,sizeof(bo));
    rei(n);
    rep1(i,1,n)
        scanf("%lf",&a[i]);
    sear_ch(1);
    printf("%.4lf
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626892.html