poj2069+hud3007(点的最小球(圆)覆盖+模拟淬火算法)

Super Star
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 3198   Accepted: 853   Special Judge

Description

During a voyage of the starship Hakodate-maru (see Problem 1406), researchers found strange synchronized movements of stars. Having heard these observations, Dr. Extreme proposed a theory of "super stars". Do not take this term as a description of actors or singers. It is a revolutionary theory in astronomy.
According to this theory, starts we are observing are not independent objects, but only small portions of larger objects called super stars. A super star is filled with invisible (or transparent) material, and only a number of points inside or on its surface shine. These points are observed as stars by us.

In order to verify this theory, Dr. Extreme wants to build motion equations of super stars and to compare the solutions of these equations with observed movements of stars. As the first step, he assumes that a super star is sphere-shaped, and has the smallest possible radius such that the sphere contains all given stars in or on it. This assumption makes it possible to estimate the volume of a super star, and thus its mass (the density of the invisible material is known).

You are asked to help Dr. Extreme by writing a program which, given the locations of a number of stars, finds the smallest sphere containing all of them in or on it. In this computation, you should ignore the sizes of stars. In other words, a star should be regarded as a point. You may assume the universe is a Euclidean space.

Input

The input consists of multiple data sets. Each data set is given in the following format.

n
x1 y1 z1
x2 y2 z2
. . .
xn yn zn

The first line of a data set contains an integer n, which is the number of points. It satisfies the condition 4 <= n <= 30.

The location of n points are given by three-dimensional orthogonal coordinates: (xi, yi, zi) (i = 1, ..., n). Three coordinates of a point appear in a line, separated by a space character. Each value is given by a decimal fraction, and is between 0.0 and 100.0 (both ends inclusive). Points are at least 0.01 distant from each other.

The end of the input is indicated by a line containing a zero.

Output

For each data set, the radius of the smallest sphere containing all given points should be printed, each in a separate line. The printed values should have 5 digits after the decimal point. They may not have an error greater than 0.00001.

Sample Input

4
10.00000 10.00000 10.00000
20.00000 10.00000 10.00000
20.00000 20.00000 10.00000
10.00000 20.00000 10.00000
4
10.00000 10.00000 10.00000
10.00000 50.00000 50.00000
50.00000 10.00000 50.00000
50.00000 50.00000 10.00000
0

Sample Output

7.07107
34.64102
 
题解:
          给定几个点,要求覆盖这些点的最小球半径。可以采用模拟淬火算法,随机选取一个点作为初始解,然后不断向当前距离最远点靠近,这是一个不断调整的过程,将对应模拟淬火算法中不断向内能最低(半径最小)这一目标函数逼近,温度对应控制变量。贴段代码:
#include<iostream>
#include<cmath>
#include<ctime>
#include<cstdio>
using namespace std;

const int MAXN=50;
const double eps=1e-8;
int n;

struct Point
{
	double x,y,z;
}myPoint[MAXN],op;

double GetDis(const Point &a,const Point &b)
{
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));
}

double Solve()
{
	double ret,delta=100.0;
	double maxDis,tempDis;
	int i,id;
	while(delta>eps)
	{
		id=0;
		maxDis=GetDis(op,myPoint[id]);
		for(i=1;i<n;i++)
		{
			tempDis=GetDis(op,myPoint[i]);
			if(tempDis>maxDis)
			{
				maxDis=tempDis;
				id=i;
			}
		}
		ret=maxDis;
		op.x+=(myPoint[id].x-op.x)/maxDis*delta;
		op.y+=(myPoint[id].y-op.y)/maxDis*delta;
		op.z+=(myPoint[id].z-op.z)/maxDis*delta;
		delta*=0.98;
	}
	return ret;
}

int main()
{
	int i;
	while(scanf("%d",&n)!=EOF)
	{
		if(0==n)break;
		for(i=0;i<n;i++)
			scanf("%lf%lf%lf",&myPoint[i].x,&myPoint[i].y,&myPoint[i].z);
		op.x=op.y=op.z=0.0;

		printf("%.5lf\n",Solve());
	}
	return 0;
}

 
上面是在三维空间内求的,下面则是平面内求的,即求最小圆覆盖。
 

Buried memory

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2213    Accepted Submission(s): 1212


Problem Description
Each person had do something foolish along with his or her growth.But,when he or she did this that time,they could not predict that this thing is a mistake and they will want this thing would rather not happened.
The world king Sconbin is not the exception.One day,Sconbin was sleeping,then swakened by one nightmare.It turned out that his love letters to Dufein were made public in his dream.These foolish letters might ruin his throne.Sconbin decided to destroy the letters by the military exercises's opportunity.The missile is the best weapon.Considered the execution of the missile,Sconbin chose to use one missile with the minimum destruction.
Sconbin had writen N letters to Dufein, she buried these letters on different places.Sconbin got the places by difficult,he wants to know where is the best place launch the missile,and the smallest radius of the burst area. Let's help Sconbin to get the award.
 

Input
There are many test cases.Each case consists of a positive integer N(N<500,^V^,our great king might be a considerate lover) on a line followed by N lines giving the coordinates of N letters.Each coordinates have two numbers,x coordinate and y coordinate.N=0 is the end of the input file.
 

Output
For each case,there should be a single line in the output,containing three numbers,the first and second are x and y coordinates of the missile to launch,the third is the smallest radius the missile need to destroy all N letters.All output numbers are rounded to the second digit after the decimal point.
 

Sample Input
     
     
     
     
3 1.00 1.00 2.00 2.00 3.00 3.00 0
 

Sample Output
     
     
     
     
2.00 2.00 1.41
 

Source
2009 Multi-University Training Contest 11 - Host by HRBEU
 
   解法完全和上面一样,在此不多说了。还是贴下代码。
#include<iostream>
#include<cmath>
#include<ctime>
#include<cstdio>
using namespace std;

const int MAXN=500+10;
const double eps=1e-8;
int n;

struct Point
{
	double x,y;
}myPoint[MAXN],op;

double GetDis(const Point &a,const Point &b)
{
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

void Solve()
{
	double ret,delta=100.0;
	double maxDis,tempDis;
	int i,id;
	while(delta>eps)
	{
		id=0;
		maxDis=GetDis(op,myPoint[id]);
		for(i=1;i<n;i++)
		{
			tempDis=GetDis(op,myPoint[i]);
			if(tempDis>maxDis)
			{
				maxDis=tempDis;
				id=i;
			}
		}
		ret=maxDis;
		op.x+=(myPoint[id].x-op.x)/maxDis*delta;
		op.y+=(myPoint[id].y-op.y)/maxDis*delta;
		delta*=0.98;
	}
	printf("%.2lf %.2lf %.2lf\n",op.x,op.y,ret);
}

int main()
{
	int i;
	while(scanf("%d",&n)!=EOF)
	{
		if(0==n)break;
		op.x=op.y=0;
		for(i=0;i<n;i++)
		{
			scanf("%lf%lf",&myPoint[i].x,&myPoint[i].y);
			op.x+=myPoint[i].x;
			op.y+=myPoint[i].y;
		}
		op.x/=n;
		op.x/=n;
		Solve();
	}
	return 0;
}

 
 

你可能感兴趣的:(ACM,模拟淬火算法,最小球覆盖)