ZOJ 3234 Protect the King

Protect the King

Time Limit: 1 Second           Memory Limit: 32768 KB

A crowd of people are planning to kill the King, who has been tyrannical for years. The King asks a group of soldiers to protect him. The soldiers stand on the ground, but NO three or more soldiers stand in a single line and NO two of them are at the same point. Each two of them can connect themselves with an iron chain. When some soldiers connect themselves in a CLOSED iron chain circle, a circle of protection is formed. The soldiers can form one, two or more circles, and the King will stand inside all circles of protection, so that it's difficult for the people to break in. The picture below shows an example of "two circles of protection", the red circle indicating the supposed position of the King.

zoj3234[Protect <wbr>the <wbr>King](凸包)

However, when iron chains of different protection circles cross each other, there may well be a chaos when the people try to break in, so it's NOT allowed that chains of different protection circles cross each other. Of course, the more circles of protection, the safer the King. Now given the coordinates of the soldiers, you are asked to calculate the maximal number of protection circles that can form.

Input

There are multiple cases(no more than 25). In each case, there's an integer n ( 2 < n <= 2000) in the first line, indicating the number of soldiers. The second line includes n pairs of integersxiyi ( 0 <= xiyi < 100000), indicating the position of the ith soldier.

Output

Print the maximal number of protection circles that can form in one line for each case.

Sample Input

4 0 0 0 1 1 0 1 1 8 0 0 8 0 8 3 0 3 2 1 2 2 3 2 3 1

Sample Output

1 2

求凸包,一层一层的,问共有多少层?...
我的思路是先求最外围凸包,然后去掉凸包上点;再依次求...

760MS -_-!险过,求路过大牛 神码......转载自
http://blog.sina.com.cn/s/blog_732dd9320100sg6m.html
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define PR 1e-8
#define N 2005
int n;
struct TPoint
{
    double x,y;
    int num;
}ply[N],ans[N],mid[N];
bool vis[N];
double cross(TPoint a,TPoint b,TPoint c)
{
    double s1=b.x-a.x;
    double t1=b.y-a.y;
    double s2=c.x-a.x;
    double t2=c.y-a.y;
    return s1*t2-s2*t1;
}
int dblcmp(double a)
{
    if(fabs(a)<PR) return 0;
    return a>0?1:-1;
}
bool cmop(TPoint a,TPoint b)
{
    if(fabs(a.x-b.x)<PR) return a.y<b.y;
    return a.x<b.x;
}
double dist(TPoint a,TPoint b)
{
    double s1=a.x-b.x;
    double s2=a.y-b.y;
    return sqrt(s1*s1+s2*s2);
}
bool cmp(TPoint a,TPoint b)
{
    int d=dblcmp(cross(ply[0],a,b));
    if(d>0) return 1;
    else if(d==0) return (dist(ply[0],a))<(dist(ply[0],b));
    else return 0;
}
void solve(int &d)
{
    int i,j,k,m,t;
    m=n;
    memset(vis,0,sizeof(vis));
    while(m>=3)
    {
        sort(ply,ply+m,cmop);
        sort(ply+1,ply+m,cmp);
        ans[0]=ply[0]; ans[1]=ply[1]; k=2;
        for(i=2;i<m;i++)
        {
            while(k>1&&(dblcmp(cross(ans[k-1],ply[i],ans[k-2])))<=0) k--;
            ans[k++]=ply[i];
        }
        d++;
        for(i=0;i<k;i++)
            vis[ans[i].num]=1;
        for(i=0,t=0;i<m;i++)
        {
            if(!vis[ply[i].num]) ply[t++]=ply[i];
        }
        m=t;
    }
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        int i,k=0;
        for(i=0;i<n;i++)
        {
            scanf("%lf%lf",&ply[i].x,&ply[i].y);
            ply[i].num=i;
        }
        solve(k);
        printf("%d\n",k);
    }
    return 0;
}



                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值