ACM气球膨胀问题C++实现

来源:互联网 发布:php开源博客系统 编辑:程序博客网 时间:2024/05/17 17:55
1.问题描述:
给定一个矩形,在该矩形中有3个固定的点,以这3个点为中心的气球先后膨胀:膨胀时触碰到矩形的边或其他气球时则停止膨胀。编写程序求以何种顺序膨胀气球时,才能使气球的横切面面积之和为最大。


解:

(1)以矩形左下角为原点,建立直角坐标系,程序输入的参数为:三个固定点的坐标,矩形的长和宽,输出膨胀顺序;

(2)程序对参数的初步处理是算得三点相互之间的距离以及三点分别与矩形的最近距离,然后穷举法列举所有的膨胀顺序,找到使三个圆半径的平方和最小的膨胀顺序;


C++函数实现及测试:

////  main.cpp//  C++////  Created by Xinhou Jiang on 6/11/16.//  Copyright © 2016 Xinhou Jiang. All rights reserved.//#include <iostream>#include <math.h>using namespace std;//气球膨胀问题//判断三者最小者函数double min(double a,double b,double c){    double min=a;    if(b<a)        min=b;    if(c<a)        min=c;    return min;}//处理气球膨胀函数void sortBall(double width,double height,double xA,double yA,double xB,double yB,double xC,double yC){    //点与点之间的距离    double distance[3];    distance[0]=sqrt(pow((xA-xB),2)+pow((yA-yB),2));    distance[1]=sqrt(pow((xA-xC),2)+pow((yA-yC),2));    distance[2]=sqrt(pow((xC-xB),2)+pow((yC-yB),2));    //点与矩形的最近距离    double minRect[3];    double minA_x=xA>width/2?(width-xA):xA;    double minA_y=yA>height/2?(height-yA):yA;    minRect[0]=minA_x;    double minB_x=xB>width/2?(width-xB):xB;    double minB_y=yB>height/2?(height-yB):yB;    minRect[1]=minB_x;    double minC_x=xC>width/2?(width-xC):xC;    double minC_y=yC>height/2?(height-yC):yC;    minRect[2]=minC_x;    int relative[3][2]={0,1,0,2,1,2};    bool stat[3]={true,true,true};//初始化三个气球状态都未膨胀    int array[3];//临时顺序    int terarray[3];//气球膨胀最终顺序    double rad[3];//膨胀后的气球半径    double powrad2=0;//半径平方和        //开始穷举    for(int i=0;i<3;i++)    {//第一个膨胀的气球        stat[i]=false;        rad[i]=min(minRect[i],distance[relative[i][0]],distance[relative[i][1]]);//第一个膨胀的气球的半径        distance[relative[i][0]]-=rad[i];        distance[relative[i][1]]-=rad[i];        array[0]=i+1;//第一个膨胀的气球编号        for(int j=0;j<3;j++)        {//第二个膨胀的气球            if(stat[j])            {                stat[j]=false;                rad[j]=min(minRect[j],distance[relative[j][0]],distance[relative[j][1]]);//第二个膨胀的气球的半径                distance[relative[j][0]]-=rad[j];                distance[relative[j][1]]-=rad[j];                array[1]=j+1;//第二个膨胀的气球编号                for(int k=0;k<3;k++)                {//第三个膨胀的气球                    if(stat[k])                    {                        rad[k]=min(minRect[k],distance[relative[k][0]],distance[relative[k][1]]);//第三个膨胀的气球的半径                        array[2]=k+1;//第三个膨胀的气球编号                        if((pow(rad[0],2)+pow(rad[1],2)+pow(rad[2],2))>powrad2)                        {                            powrad2=(pow(rad[0],2)+pow(rad[1],2)+pow(rad[2],2));                            terarray[0]=array[0];                            terarray[1]=array[1];                            terarray[2]=array[2];                        }                        cout<<array[0]<<endl;                        cout<<array[1]<<endl;                        cout<<array[2]<<endl;                        cout<<"-------------------"<<endl;                    }                }//第三个膨胀的气球                //恢复第二个气球初始状态                //点与点之间的距离                distance[relative[j][0]]+=rad[j];                distance[relative[j][1]]+=rad[j];                stat[j]=true;//恢复第二个气球状态都未膨胀            }        }//第二个膨胀的气球        //恢复初始状态        //点与点之间的距离        distance[0]=sqrt(pow(xA-xB,2)+pow(yA-yB,2));        distance[1]=sqrt(pow(xA-xC,2)+pow(yA-yC,2));        distance[2]=sqrt(pow(xC-xB,2)+pow(yC-yB,2));        stat[0]=true;//恢复三个气球状态都未膨胀        stat[1]=true;        stat[2]=true;    }//第一个膨胀的气球    cout<<"最佳膨胀顺序为:"<<terarray[0]<<"-"<<terarray[1]<<"-"<<terarray[2]<<endl;}//主函数测试int main(){    sortBall(20,10,3,5,4,2,8,5.5);    return 0;}

1 0