zoukankan      html  css  js  c++  java
  • HDU 4946 Area of Mushroom 凸包 第八次多校

    题目链接:hdu 4946

    题意:一大神有N个学生,各个都是小神,大神有个二次元空间,每一个小神都有一个初始坐标,如今大神把这些空间分给徒弟们,规则是假设这个地方有一个人比谁都先到这,那么这个地方就是他的,问谁的地盘面积是无穷大的.

    思路:由于空间是无限大的,所以仅仅要速度最大就有可能有无限的地盘,重合的点不能严格的比对方快,也不符合规定,然后求速度最大的点围城的凸包,凡是在凸包上的点且不重合的,地盘都是无穷大.

    比赛的时候,不会凸包的,现找的模板,不了解性能,不知道计算凸包不能传重合的点进去结果WA出翔


    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <queue>
    #include <vector>
    #include <algorithm>
    
    #define INF 1e9
    #define maxn 1000
    #define EPS 1e-6
    
    #define N 1000
    using namespace std;
    struct point
    {
        int x,y;  //横纵坐标 : x,y
        double len,theta;  //与參考点的距离 len 与參考点构成的向量与 (1,0)向量构成的夹角的余弦值 theta
    }g[N]; //定义了一个全局变量,记录凸包中的点
    /*--------按余弦值,从大到小高速排序--------*/
    void qsort(int st,int en)
    {
        int i=st,j=en;
        g[0]=g[i];
        while(i<j)
        {
            while(i<j && g[0].theta>=g[j].theta) j--;
            if(i<j) { g[i]=g[j]; i++; }
            while(i<j && g[0].theta<=g[i].theta) i++;
            if(i<j) { g[j]=g[i]; j--; }
        }
        g[i]=g[0];
        if(st<i-1) qsort(st,i-1);
        if(i+1<en) qsort(i+1,en);
    }
    
    /*-----------Graham 扫描法-------------*/
    void graham(int *n)
    {
        /*第一步,寻找y坐标最小,然后x坐标最小的点*/
        int p=1;
        for(int i=2;i<=*n;i++)
          if((g[i].y<g[p].y)||(g[i].y==g[p].y && g[i].x<g[p].x)) p=i;
        g[0]=g[p]; g[p]=g[1]; g[1]=g[0];
        /*找到该点,并把它存放在 g 中的第一个元素的位子上*/
        
        /*第二步,计算全部的点距离參考点的距离(len) 还有夹角的余弦值 (theta)*/
        for(int i=2;i<=*n;i++)
        {
            g[i].len=sqrt((g[i].x-g[1].x)*(g[i].x-g[1].x)+(g[i].y-g[1].y)*(g[i].y-g[1].y));
            g[i].theta=100*(g[i].x-g[1].x)/g[i].len;
        }
        qsort(2,*n);//先依据夹角的余弦值从大到小排序
        
        /*第三步,将全部theta值相等的点,仅仅保存len值最大的,存放在数组map中*/
        point map[N];
        int tot=0; p=1;
        while(p<=*n)
        {
            int k=p;
            while(fabs(g[p].theta-g[p+1].theta)<=EPS)
            {
                if(g[p+1].len>g[k].len) k=p+1;
                p++;
            }
            map[++tot]=g[k];
            p++;
        }
        
        /*第四步,对map中的元素扫描一遍,确定凸包的元素,放在数组g中*/
        *n=tot; tot=3; //先做了一个小小的处理,使得自己更好理解
        memset(g,0,sizeof(g));
        g[1]=map[1]; g[2]=map[2]; g[3]=map[3]; //先将前三个点入栈 g 
        for(int i=4;i<=*n;i++)  //依次用map中的每一个点对g中的点进行一次推断,看是否是属于凸包
        {
            double chaji=(g[tot].x-g[tot-1].x)*(map[i].y-g[tot].y)-(map[i].x-g[tot].x)*(g[tot].y-g[tot-1].y);
            for(;chaji<=0 && tot>=1;) //假设旋转的方向不同,g[tot]这个点就不是,删除,并继续推断 g 中下一个点是不是
            {
                tot--;
                chaji=(g[tot].x-g[tot-1].x)*(map[i].y-g[tot].y)-(map[i].x-g[tot].x)*(g[tot].y-g[tot-1].y);
            }
            g[++tot]=map[i]; //将map[i]这个点入栈,至于是否是属于凸包中的点,等待以后的点来推断
        }
        *n=tot;//凸包处理完,总共同拥有tot个凸包上的点
    }
    
    
    
    
    
    
    
    /*---------------------------------------------------------------------------------------------*/
    
    struct Node{
    	int x,y,v,rank,bl;
    }tmp;
    int maxe;
    vector<Node> stu;
    int cas=0;
    bool cmp(Node a,Node b)
    {
    	return a.rank<b.rank;
    }
    void init(int n)
    {
    	stu.clear();
    	maxe=0;
    	for(int i=0;i<n;i++)
    	{
    		scanf("%d %d %d",&tmp.x,&tmp.y,&tmp.v);
    		tmp.rank=i;
    		tmp.bl=0;
    		stu.push_back(tmp);
    		maxe=max(tmp.v,maxe);
    	}
    }
    bool check(int a,int b,int tt)
    {
    	int c;
    	if(b==tt)
    	{
    		c=1;
    	}else 
    	{
    		c=b+1;
    	}
    	 double chaji=(g[c].x-g[b].x)*(stu[a].y-g[c].y)-(stu[a].x-g[c].x)*(g[c].y-g[b].y);
    	 if(chaji<=EPS) return 1;
    	 else return 0;
    }
    
    int main()
    {
    	//freopen("data.in","r",stdin);
    	int n;
    	while (~scanf("%d",&n))
    	{	
    		if(n==0) break;
    		printf("Case #%d: ",++cas);
    		init(n);
    		
    		
    		
    		
    		if(maxe==0)
    		{
    			for(int i=0;i<n;i++)
    			{
    				printf("0");
    			}
    		}
    		else 
    		{
    			for(int i=0;i<n;i++)
    			{
    				if(stu[i].v==maxe)
    				{
    					stu[i].bl=1;
    				}
    			}
    			for(int i=0;i<n-1;i++)
    			{
    				if(stu[i].bl==1)//错误写法: if(stu[i].v=maxe)
    				{
    					for(int j=i+1;j<n;j++)
    					{
    						if(stu[i].x==stu[j].x&&stu[i].y==stu[j].y&&stu[i].v==stu[j].v&&i!=j)
    						{
    							stu[j].bl=0;
    							stu[i].bl=-1;
    						}
    					}
    				}
    			}
    			int tt=0;
    			for(int i=0;i<n;i++)
    			{
    				if(stu[i].v==maxe&&stu[i].bl!=0)
    				{	g[++tt].x=stu[i].x;
    					g[tt].y=stu[i].y;
    				}
    			}
    			//printf("%d
    ",tt);
    			if(tt>=3)
    			{
    				graham(&tt);
    				for(int i=0;i<n;i++){
    					if(stu[i].bl==1){
    						stu[i].bl=0;
    						for(int j=1;j<=tt;j++)
    						{
    							if((stu[i].x==g[j].x&&stu[i].y==g[j].y)||check(i,j,tt))
    							{
    								stu[i].bl=1;
    								break;
    							}
    						}
    					}
    				}
    			}
    			sort(stu.begin(),stu.end(),cmp);
    			for(int i=0;i<n;i++)
    			{
    				if(stu[i].bl==-1)
    					stu[i].bl=0;
    				printf("%d",stu[i].bl);
    			}
    		}
    
    		
    		puts("");
    	}
    	return 0;
    }






  • 相关阅读:
    django ajax报错解决:You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set.
    django使用session报错:no such table: django_session
    centos7下yum安装mariadb
    pip报错解决:EnvironmentError: mysql_config not found
    django报错解决:view must be a callable or a list/tuple in the case of include().
    onpageshow和onpagehide
    深入理解Linux的CPU上下文切换
    看完就彻底懂了红黑树!红黑树的插入、删除、左旋、右旋
    shell根据csv生成sql
    shell中的EOF用法
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4197182.html
Copyright © 2011-2022 走看看