• hoj 1061 排列树问题


    Problem C:排列树问题

    Time Limit:5000MS  Memory Limit:65536K
    Total Submit:55 Accepted:3

    Description

    试设计一个用回溯法搜索排列空间树的函数。该函数的参数包括结点可行性判定函数和上界函数等必要的函数,并将此函数用于解圆排列问题。
    圆排列问题描述如下:给定n 个大小不等的圆c1 , c2 ,..., cn ,现要将这n 个圆排进一个矩形框中,且要求各圆与矩形框的底边相切。圆排列问题要求从n 个圆的所有排列中找出有最小长度的圆排列。例如,当n=3,且所给的3 个圆的半径分别为1,1,2 时,这3 个圆的最小长度的圆排列是1,2,1,其最小长度为2 + 4*sqr(2)。
    编程任务:
    对于给定的n(n≤≡10)个圆,编程计算最小长度排列。

    Input

    输入由多组测试数据组成。
    每组测试数据输入的第一行是1 个正整数n,表示有n个圆。第2行有n个正数,分别表示n个圆的半径。

    Output

    对应每组输入,输出的每行是计算出的最小长度,保留3 位小数。

    Sample Input

    3
    1 1 2

    Sample Output

    7.657

    [Submit]   [Go Back]   [Status]   [Clarify]

     

    #include <iostream>
    #include 
    <cmath>
    #define MAX 13
    using namespace std;
    int nn;
    class Circle
    {
    private:
        
    double mmin,  //??????????
            x[MAX],   //????????????????????
            r[MAX];  //??????????
        int n;   //??????????????
    public:
        Circle()
        {
            mmin
    =100000000;
        }
        
    void Set();
        
    void Swap(int i,int j);
        
    double Center(int t);
        
    void Computer();
        
    void Backtrack(int t);
        
    double GetMmin();
    };
    void Circle::Set()
    {
        
    int i;
        n
    =nn;
        
    for(i=1;i<=n;i++)
        {
            scanf(
    "%lf",&r[i]);
            x[i]
    =0;
        }
    }
    void Circle::Swap(int i,int j)
    {
        
    double temp;
        temp
    =r[i];
        r[i]
    =r[j];
        r[j]
    =temp;
    }
    double Circle::Center(int t)  //????????????????????????????
    {
        
    int j;
        
    double temp=0,valuex;
        
    for(j=1;j<t;j++)
        {
            valuex
    =x[j]+2.0*sqrt(r[t]*r[j]);
            
    if(valuex>temp)
                temp
    =valuex;
        }
        
    return temp;
    }
    void Circle::Computer()   //??????????????????
    {
        
    double low=0,high=0;
        
    int i;
        
    for(i=1;i<=n;i++)
        {
            
    if(x[i]-r[i]<low)
                low
    =x[i]-r[i];
            
    if(x[i]+r[i]>high)
                high
    =x[i]+r[i];
        }
        
    if(high-low<mmin)
            mmin
    =high-low;
    }
    void Circle::Backtrack(int t)
    {
        
    int j;
        
    double centerx;
        
    if(t>n)
            Computer();
        
    else
        {
            
    for(j=t;j<=n;j++)
            {
                Swap(t,j);
                centerx
    =Center(t);
                
    if(centerx+r[t]+r[1]<mmin)
                {
                    x[t]
    =centerx;
                    Backtrack(t
    +1);
                }
                Swap(t,j);
            }
        }
    }
    double Circle::GetMmin()
    {
        
    return mmin;
    }
    /*double Circle::CirclePerm(int n,double *a)
    {
        Circle X;
        X.n=n;
        X.r=a;
        X.mmin=1000000000;
        double *x=new double[n+1];
        X.x=x;
        X.Backtrack(1);
        delete [] x;
        return X.mmin;
    }
    */
    int main()
    {
        
    while(cin>>nn)
        {
            Circle X;
            X.Set();
            X.Backtrack(
    1);
            printf(
    "%0.3lf\n",X.GetMmin());
        }
        
    return 0;
    }


     

  • 相关阅读:
    0529学习进度条
    0523-学习进度条
    0515-学习进度条
    实验三-进程模拟调度
    0501-学习进度条
    0424-学习进度条
    0422—操作系统作业调度
    0415-同学博客评价
    0414-复利计算再升级
    0409-学习进度条
  • 原文地址:https://www.cnblogs.com/forever4444/p/1495970.html
Copyright © 2020-2023  润新知