HOJ13832 Fence

来源:互联网 发布:mac 体验 编辑:程序博客网 时间:2024/06/05 04:28

Problem descriptionM-O (Microbe-Obliterator) is a tiny robot, programmed to clean any microbes it detects in the Axiom, a starliner spacecraft built by the Buy n Large (BNL) corporation. Tonight M-O is too busy since the great hall of the Axiom is a mess. A number of foreign microbes have attacked the spacecraft and are spread on the floor of the great hall. It’s M-O’s duty to wipe all those microbes.
The floor of the great hall is an infinite grid of 1×1 cells. The 4 edges and the 2 diagonals of each cell are drawn as white segments. The microbes are currently located only on the corners of the cells.
Since the cleaning job might take a lot of time, M-O needs to build a protector fence around the microbes as soon as possible, to keep the Axiom residents safe and to prevent the microbes from spreading to the other areas of the spacecraft. Since M-O is very regular, it makes the fence as a single closed region with borders only on the white segments (cell edges and diagonals). All microbes should be located inside the fence, or on its borders.
Given the map of the microbes, your task is to help M-O build a fence with the minimum perimeter.InputThere are multiple test cases in the input. Each test case starts with a line containing a single integer n, the number of microbes in the great hall (0 ⩽ n ⩽ 10000). Each of the next n lines contains two integers xi and yi, denoting the coordinates of the i-th microbe. The absolute value of all coordinates is guaranteed to be at most 106. The coordinates are reported based on some arbitrary grid cell corner, taken as the coordinates origin. The input terminates with a line containing a single zero, which should not be considered as a test case.OutputIt is clear that the perimeter length of any fence built over the edges and diagonals of the grid can be uniquely written as where a and b are two non-negative integer numbers. For each test case, write a single line containing the two integers a and b with the assumption that the perimeter length of the fence with the minimum perimeter is . Note that a fence must be seen as a closed path; therefore if two parts of the fence overlap, the overlapped part must be taken into account twice.Sample Input

112 23 23 07 13 51 47 45 40 27 22 021 33 10
Sample Output
12 60 4
Problem SourceAsia Region, Tehran Site,Sharif University of Technology, 24?25 December 2015题意剖析:即给出点的坐标,求最小凸包(凸包是什么?自行百度),其中这里的凸包有限制,即只能沿平行于坐标轴或正方形对角线走。最后求凸包的周长,表示为,输出a和b。


思路:如果求最小凸包时同时考虑其限制条件,会让这道题变复杂。我们不妨先用Andrew算法(不懂??自己百度)求出最小凸包

,记录构成最小凸包的点是哪些。最后把前后两个点依次取出,根据限制特殊化处理其周长问题!


AC代码如下:

#include<iostream>#include<string>#include<vector>#include<string.h>#include<set>#include<algorithm>#include<queue>#include<map>#include<stdio.h>#include<math.h>using namespace std;struct Points{    long long x;    long long y;};struct Points point[10005],result[10005];//result用来记录构成凸包的点long long n,a,b;bool Compare(struct Points a,struct Points b){    if(a.x<b.x){        return true;    }else if(a.x==b.x&&a.y<b.y){        return true;    }else{        return false;    }    }bool Cross(struct Points p1,struct Points p2,struct Points q1){//用来判断两线段的相对位置    if(((p1.x-q1.x)*(p2.y-q1.y)-(p2.x-q1.x)*(p1.y-q1.y))<=0)        return true;    else        return false;}
//Andrew算法核心代码long long ConvexHull(struct Points *p,long long  n,struct Points *ch){    sort(p,p+n,Compare);    long long  m=0;    for(int i=0;i<n;i++){        while(m>1&&Cross(p[i],ch[m-1],ch[m-2]))m--;        ch[m++]=p[i];    }    int k=m;    for(int i=n-2;i>=0;i--){        while(m>k&&Cross(p[i],ch[m-1],ch[m-2]))m--;        ch[m++]=p[i];    }    if(n>1)m--;    return m;}int main(){    cin.sync_with_stdio(false);//这个可忽略,只是用来减低时间复杂度的小操作    while(cin>>n&&n){    a=0;b=0;    for(int i=0;i<n;i++){        cin>>point[i].x>>point[i].y;    }     long long pp=ConvexHull(point,n,result);/*    cout<<pp<<endl;    for(int i=0;i<=pp;i++){        cout<<result[i].x<<" "<<result[i].y<<endl;    }*/
//计算周长    for(int i=0;i<pp;i++){        if(result[i].x==result[i+1].x){        //    cout<<"1"<<endl;            a+=abs(result[i].y-result[i+1].y);        }else if(result[i].y==result[i+1].y){        //    cout<<"2"<<endl;            a+=abs(result[i].x-result[i+1].x);         }else if(abs(result[i].x-result[i+1].x)==abs(result[i].y-result[i+1].y)){        //    cout<<"3"<<endl;            b+=abs(result[i].x-result[i+1].x);        }else{        //    cout<<"4"<<endl;            b+=min(abs(result[i].x-result[i+1].x),abs(result[i].y-result[i+1].y));            a+=abs(abs(result[i].x-result[i+1].x)-abs(result[i].y-result[i+1].y));        }    //    cout<<a<<" "<<b<<endl;    }    cout<<a<<" "<<b<<endl;}    return 0;}

时间复杂度为O(2nlog(n)),一次AC!

原创粉丝点击