油滴擴展 題解

油滴擴展

【問題描述】

在一個長方形框子裏,最多有N(0≤N≤6個相異的點。在其中任何一個點上放一個很小的油滴,那麼這個油滴會一直擴展,直到接觸到其他油滴或者框子的邊界。必須等一個油滴擴展完畢才能放置下一個油滴。那麼應該按照怎樣的順序在這N個 點上放置油滴,才能使放置完畢後所有油滴佔據的體積最大呢?(不同的油滴不會相互融合)

注:圓的面積公式 V=pi*r*r,其中r爲圓的半徑。

【輸入】

第一行一個整數N

第二行爲長方形邊框一個頂點及其對角頂點的座標,x , y , x’, y’。

接下去N行,每行兩個整數xi,yi,表示盒子內N個點的座標。

以上所有的整數都在[-1000,1000]內。

【輸出】

一行,一個整數,長方形盒子剩餘的最小空間(結果四捨五入輸出)。

【輸入樣例】

2

0  0  10  10

3   3 

7   7

【輸出樣例】

50



+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

哎,今天的測試成績實在是太差,這樣的情況已經持續恆久了,離比賽沒剩幾天,我可不想然我自己後悔,我必須努力衝刺了……加油!!我一定能行!!

廢話也不多說了,直接進入正題吧……

這道題n很小,所以我們可以直接用裸的dfs,具體實現就不說了,看這篇文章的都是大神,我就說一下注意事項吧

注意:

1.n有可能爲0

2.可能存在折樣一種情況,即,當前點已經在一個油滴擴展後的範圍之內,也可以表達成,這個油滴將要擴展的半徑爲負。這時我們就要把這樣的半徑賦值爲0

3.四捨五入的有關實現一定要注意,尤其是當n=0時,別忘了!

本若菜在寫這題之前忘了如何用四捨五入的函數了,所以手打了一個,見笑了……

+++++++++++++++++++++++++++++代碼如下++++++++++++++++++++++++++++++++++++++++

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define pi 3.1415926
using namespace std;
double d[15][15],ans,dis,r[15];
int n,x[15],y[15],b[15];
int ok()
{
	for(int i=2;i<=n+1;i++)
		if(!b[i])return 0;
	return 1;
}

double mmin(double x,double y,double z,double p)
{
	double num=min(x,y);
	num=min(num,z);
	num=min(num,p);
	return num;
}

void dfs()
{
	if(ok()){dis=max(dis,ans);return;}
	for(int i=2;i<=n+1;i++)
	if(!b[i])
	{
		double minc=mmin(abs(x[i]-x[0]),
				         abs(x[i]-x[1]),
				         abs(y[i]-y[0]),
			             abs(y[i]-y[1]));
		for(int j=2;j<=n+1;j++)
			if(j!=i&&b[j])
			  minc=min(minc,d[i][j]-r[j]);
		if(minc<0)minc=0;
		b[i]=1;ans+=(minc*minc);
		r[i]=minc;
		dfs();
		b[i]=0;ans-=(minc*minc);r[i]=0;
	}
}

int main()
{
	scanf("%d",&n);
	cin>>x[0]>>y[0]>>x[1]>>y[1];
	if(n==0)
	{
		ans=abs(x[0]-x[1])*abs(y[0]-y[1]);
		if(ans-(int)ans<0.5)ans=floor(ans);
		else ans=floor(ans)+1; 
		cout<<(int)ans;
		return 0;
	}
	for(int i=2;i<=n+1;i++)
		cin>>x[i]>>y[i];
	for(int j=2;j<=n+1;j++)
	 for(int i=2;i<=n+1;i++)
	  if(i!=j)
	 	d[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])
		 				+(y[i]-y[j])*(y[i]-y[j]));
	dfs();
	ans=abs(x[0]-x[1])*abs(y[0]-y[1])-pi*dis;
	if(ans-floor(ans)>=0.5)ans=floor(ans)+1;
	else ans=floor(ans); 
	cout<<ans; 
	return 0;
}



由於對於實型的操作較弱,下一篇文章將介紹一下對於實型的那些操作……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章