Wall
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2371 Accepted Submission(s): 652
Problem DescriptionOnce upon a time there was a greedy King who ordered his chief Architect to build a wall around the King's castle. The King was so greedy, that he would not listen to his Architect's proposals to build a beautiful brick wall with a perfect shape and nice tall
towers. Instead, he ordered to build the wall around the whole castle using the least amount of stone and labor, but demanded that the wall should not come closer to the castle than a certain distance. If the King finds that the Architect has used more resources
to build the wall than it was absolutely necessary to satisfy those requirements, then the Architect will loose his head. Moreover, he demanded Architect to introduce at once a plan of the wall listing the exact amount of resources that are needed to build
the wall.
Your task is to help poor Architect to save his head, by writing a program that will find the minimum possible length of the wall that he could build around the castle to satisfy King's requirements.
The task is somewhat simplified by the fact, that the King's castle has a polygonal shape and is situated on a flat ground. The Architect has already established a Cartesian coordinate system and has precisely measured the coordinates of all castle's vertices
in feet.
InputThe first line of the input file contains two integer numbers N and L separated by a space. N (3 <= N <= 1000) is the number of vertices in the King's castle, and L (1 <= L <= 1000) is the minimal number of feet that King allows for the wall to come close to
the castle.
Next N lines describe coordinates of castle's vertices in a clockwise order. Each line contains two integer numbers Xi and Yi separated by a space (-10000 <= Xi, Yi <= 10000) that represent the coordinates of ith vertex. All vertices are different and the sides
of the castle do not intersect anywhere except for vertices.
OutputWrite to the output file the single number that represents the minimal possible length of the wall in feet that could be built around the castle to satisfy King's requirements. You must present the integer number of feet to the King, because the floating numbers
are not invented yet. However, you must round the result in such a way, that it is accurate to 8 inches (1 foot is equal to 12 inches), since the King will not tolerate larger error in the estimates.
This problem contains multiple test cases!
The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.
The output format consists of N output blocks. There is a blank line between output blocks.
Sample Input
19 100200 400300 400300 300400 300400 400500 400500 200350 200200 200
Sample Output
1628
SourceNortheastern Europe 2001
RecommendJGShining
這個題目赤裸裸的凸包問題了,但是過的比例和人數不多有點不解,估計是pe造成的,在杭電上總是喜歡在格式上下功夫,不解,POJ上也有這個題目,不過在格式上要求簡單多了!graham掃描法來尋找凸包,看了別人的代碼好多都應以一些棧什麼的輔助數組但是我沒有,全部都是在一個數組裡面完成,其實是完全可以的。因為我們在選擇或者淘汰的時候從前面向後面,那麼前面搞定後的數組就可以利用了嘛因為留下來的總是比原來要少的!下面具體介紹一下程式步驟:第一步:尋找最下面的點,也就是y值最小的點,這個點毫無疑問是凸包上面的點,也可以知道這個點是我們第一個找到在凸包上的點第二步:按照極角排序,就是按照,因為這裡用的是qsort那麼在排序的時候每次涉及到兩個點,那麼這兩個點誰在前面,誰在後面就要有一個比較,這個比較函數就是int cmp(const void *a,const void *b)
{
return across(po[0],*(point*)a,*(point*)b) > 1e-8 ? -1 : 1;
}根據兩點和最低點組成三角形的面積正負來作為判斷條件,達到按照極角排序的效果第三步:去除一些一定不會在凸包上的點,也就是最低點和另外兩個點共線的情況,那麼只要留下離最低點遠的那個點第四步:前面的都是輔助,這裡是核心,從剩下的點中選擇在凸包上的點,首先明確一點,假設只有三個點,那麼經過上面幾步之後剩下來的三個點一定可以組成凸包那麼首先前三個放在凸包裡面,然後開始選擇,選擇的時候以這樣方式選擇for(i=3;i<num;i++)
{
while(across(po[k-1],po[k],po[i]) < -eps)
{k--;}
po[++k]=po[i];//就這個迴圈結束,不需要了!
}最後選擇的兩個在凸包上的點,和當前正要選擇的點會組成一個三角形,如果面積為正,那麼可以選擇,如果面積為負,那麼說明先前選擇的那個點有問題造成了不是凸包,應該去除,所以k--,接下來迴圈判斷,這樣就保證了已經選擇的點的一個凸性最後強調一點小技巧,在graham掃描的時候把第一個點加到最後,這樣能省很多事情,減少個邊界情況的考慮!
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <cmath>using namespace std;#define eps 1e-6#define PI 3.14159265struct point{double x;double y;}po[1500],temp;int n,l,pos;bool zero(double a){return fabs(a) < eps;}double dis(point &a,point &b)//返回兩點之間距離的平方{return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);}double across(point &a,point &b,point &c)//求a b and a c 的X積{return (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x);}int cmp(const void *a,const void *b){return across(po[0],*(point*)a,*(point*)b) > 1e-8 ? -1 : 1;}int select(){int i,j,k=1;for(i=2;i<n;i++){if(zero(across(po[0],po[k],po[i]))){if(dis(po[0],po[k]) < dis(po[0],po[i]))po[k]=po[i];}elsepo[++k]=po[i];}return k+1;}int graham(int num){double ans=PI*l*2;int i,j,k=2;po[num]=po[0];//fangbian num++;for(i=3;i<num;i++){while(across(po[k-1],po[k],po[i]) < -eps){k--;}po[++k]=po[i];//就這個迴圈結束,不需要了!}for(i=1;i<=k;i++){ans+=sqrt(dis(po[i-1],po[i]));}if(ans-int(ans) > 0.5)printf("%d\n",int(ans)+1);elseprintf("%d\n",int(ans));return 0;}int main(){int i,j,k;point my_temp;int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&l);scanf("%lf%lf",&po[0].x,&po[0].y);temp=po[0];pos=0;for(i=1;i<n;i++){scanf("%lf%lf",&po[i].x,&po[i].y);if(po[i].y < temp.y)temp=po[i],pos=i;}my_temp=po[0];po[0]=po[pos];po[pos]=my_temp;qsort(po+1,n-1,sizeof(po[0]),cmp);graham(select());if(t>0)printf("\n");}return 0;}