poj 1319 Pipe Fitters

Pipe Fitters

以下思路來源於:http://www.cnblogs.com/devymex/archive/2010/08/15/1799966.html

Time limit: 3.000 seconds
限時:3.000秒

Background
背景

Filters, or programs that pass "processed" data through in some changed form, are an important class of programs in the UNIX operating system. A pipe is an operating system concept that permits data to "flow" between processes (and allows filters to be chained together easily.)
在UNIX操作系統中,過濾器是重要的一類程序。通過它“處理”的數據,其格式會發生改變。管道是操作系統中的一個概念,它使得數據可以在進程間流動(也很容易和過濾器相連,協同工作)。

This problem involves maximizing the number of pipes that can be fit into a storage container (but it's a pipe fitting problem, not a bin packing problem).
這個問題是關於使裝入貯藏箱的管子數量最大化(這是關於管子貯藏的問題,不是裝箱問題)。

The Problem
問題

A company manufactures pipes of uniform diameter. All pipes are stored in rectangular storage containers, but the containers come in several different sizes. Pipes are stored in rows within a container so that there is no space between pipes in any row (there may be some space at the end of a row), i.e., all pipes in a row are tangent, or touch. Within a rectangular cross-section, pipes are stored in either a grid pattern or a skew pattern as shown below: the two left-most cross-sections are in a grid pattern, the two right-most cross-sections are in a skew pattern.
一家公司生產一種直徑相同的管子。所有管子都存儲在矩形貯藏箱中,但貯藏箱的尺寸大小不一。管子按行排列在一個貯藏箱內,以使每行管子之間沒有任何的空隙(在一行的兩端可能存在空隙),也就是說所有放在同一行的管子都是相切的,或說是外接的。下圖顯示了一個貯藏箱的矩形橫截面,可以看到管子只按“網格”和“交錯”兩種方式裝入:左邊的兩組橫截面是“網格”方式,右邊的兩組橫截面是“交錯”方式。

管道

Note that although it may not be apparent from the diagram, there is no space between adjacent pipes in any row. The pipes in any row are tangent to (touch) the pipes in the row below (or rest on the bottom of the container). When pipes are packed into a container, there may be "left-over" space in which a pipe cannot be packed. Such left-over space is packed with padding so that the pipes cannot settle during shipping.
注意,任何一行相鄰的管子間都沒有間隔,這可能在圖中看不清楚。每行管子都與下一行管子相切(外接),最底下一行與貯藏箱底相切。當管子裝入貯藏箱後,可能會留下一些不夠放進一個管子的空間。因此需要將這些空間填充滿,否則船運將無法啓程。

The Input
輸入

The input is a sequence of cross-section dimensions of storage containers. Each cross-section is given as two real values on one line separated by white space. The dimensions are expressed in units of pipe diameters. All dimensions will be less than 27. Note that a cross section with dimensions a×b can also be viewed as a cross section with dimensions b×a.
輸入是一組 貯藏箱橫截面的尺寸。每個橫截面數據獨佔一行,給出兩個實數值,中間以空格隔開。尺寸的單位就是 一個管子的直徑。所有尺寸都小於27。注意,尺寸爲a×b的橫截面,也可看做是b×a的

The Output
輸出

For each cross-section in the input, your program should print the maximum number of pipes that can be packed into that cross section. The number of pipes is an integer -- no fractional pipes can be packed. The maximum number is followed by the word "grid" if a grid pattern results in the maximal number of pipes or the word "skew" if a skew pattern results in the maximal number of pipes. If the pattern doesn't matter, that is the same number of pipes can be packed with either a grid or skew pattern, then the word "grid" should be printed.
對應於每一行橫截面的輸入,你的程序要打印出在這個橫截面中能裝入管子的最大數量。該數量由一個整數表示——不存在半個管子的情況。後面輸出一個單詞“grid”或着“skew”,分別表示達到最大數量的裝法是網格或交錯。如果兩種裝法都能夠達到相同的最大數量,則輸出“grid”。

Sample Input
輸入示例

3 3
2.9 10
2.9 10.5
11 11

Sample Output
輸出示例

9 grid
29 skew
30 skew
126 skew


Analysis
分析

這是很有意思的一道數學題。按題目要求每行管子之間不能有空隙,因此任意上下兩個管子的位置關係只能有兩種:正對或60度斜錯,其它的角度都會使上一行或下一行的管子間產生空隙。題目還給出管子的直徑是一個單位,這樣問題就簡單多了。那麼如果是網格方式排列(即上下正對),那麼直接將貯藏箱的長寬取整即爲可容納管子的數量。

如果是交錯排列(上下行斜錯60度),情況稍有點複雜。爲方便描述,我們把箱子最底一的一行稱爲第0行,之上一行爲第1行,以此類推。第0行的行高顯然爲直徑,從第1行開始向上,每行的行高都爲下面一行的頂到這一行頂的距離。該行高可簡單的用勾股定理計算,方法見下圖:


skew

圖中r爲半徑,d爲直徑,紅色等邊三角形的頂點分別爲三個管子橫截面的圓心。可以看出,上面一行的行高即等於該三角形的高,由此可計算出貯藏箱一共可以放多少行。但列的情況又稍有不同,如下圖所示:

skew1

如果最底一行在放滿管子後,剩下的空間大於半徑,那麼上面的所有行都可放置相同數量的管子。但如果剩下的空間不足半徑,那麼奇數行就只能放下的數量就比偶數行少1個。爲方便計算,可先按每行相同數量的管子乘以行數,得到所有的管子數量,然後減掉不能放下的奇數行的管子。具體實現方法詳見下面代碼中的註釋。特別強調:

要注意輸入的數據可能小於1的情況。

#include<iostream>
using namespace std;
#include<math.h>
const double P=sqrt(3.0)/2.0;
const double eps=1e-8;
int main()
{
	int max1,max2,max3,max,t;
	double a,b;
	while(cin>>a>>b)
	{
		max1=floor(a)*floor(b);
		max2=floor(a);
		t=1;
		while(1)
		{
			t++;
			if(b-(t-1)*P-1<eps)
				break;
			if(t%2==0)
		    	max2+=floor(a-0.5);
			else max2+=floor(a);
		}
		max3=floor(b);
		t=1;
		while(1)
		{
			t++;
			if(a-(t-1)*P-1<eps)
				break;
			if(t%2==0)
	    		max3+=floor(b-0.5);
			else
				max3+=floor(b);
		}
		max=max1;
		if(max<max2)
			max=max2;
		if(max<max3)
			max=max3;
		if(a-1.0<eps||b-1.0<eps)
			max=0;
		if(max==max1)
			cout<<max<<" "<<"grid"<<endl;
		else
			cout<<max<<" "<<"skew"<<endl;
	}
	return 0;
}


 


#include<iostream>
using namespace std;
#include<math.h>
const double P=sqrt(3.0)/2.0;
const double eps=1e-8;
int main()
{
	int max1,max2,max3,max,t;
	double a,b;
	while(cin>>a>>b)
	{
		max1=floor(a)*floor(b);
		max2=floor(a);
		t=1;
		while(1)
		{
			t++;
			if(b-(t-1)*P-1<eps)
				break;
			if(t%2==0)
		    	max2+=floor(a-0.5);
			else max2+=floor(a);
		}
		max3=floor(b);
		t=1;
		while(1)
		{
			t++;
			if(a-(t-1)*P-1<eps)
				break;
			if(t%2==0)
	    		max3+=floor(b-0.5);
			else
				max3+=floor(b);
		}
		max=max1;
		if(max<max2)
			max=max2;
		if(max<max3)
			max=max3;
		if(a-1.0<eps||b-1.0<eps)
			max=0;
		if(max==max1)
			cout<<max<<" "<<"grid"<<endl;
		else
			cout<<max<<" "<<"skew"<<endl;
	}
	return 0;
}


 

 

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