zoukankan      html  css  js  c++  java
  • fafu 1413

    叉积的运用 ,不断的用叉积去判断 最小的拼图, 刚开始对点进行排序,每个人的排序规则不同做法可能不同,我是按照点的x轴进行x轴相同用y小的在前面,然后每个点按照最下的点开始进行查找 每次从一个点出发然后结束后无论找不找到都得 将出发的那条边删掉,ok然后就可以不断的去瓜分这张大的图,

    #include <iostream>
    #include <cstdio>
    #include<string.h>
    #include<cmath>
    #include<algorithm>
    #include<map>
    #include<vector>
    using namespace std;
    struct point
    {
        double x,y;
        point(double a=0,double b=0)
        {x=a;y=b;}
    }node[1500],tong[1500];
    struct line
    {
        point p1,p2;
    }L[1005];
    point operator -(point a,point b){  return point(a.x-b.x,a.y-b.y);    }
    bool operator <(const point &a,const point &b)
    { return a.x<b.x||(a.x==b.x&&a.y<b.y);}
    bool operator ==(const point &a,const point &b){ return a.x==b.x&&a.y==b.y;    }
    int n,sum,num[1500],ct;
    double A[1500];
    bool mark[1500];
    int vis[1500];
    bool cmp(point a,point b)
    {return a.x<b.x||(a.x==b.x&&a.y<b.y);}
    map<point,int>P;
    vector<int>F[1500];
    double area(int T)
    {
        double sum=0;
        tong[T]=tong[0];
        for(int i=0;i<T;i++)
        sum+=tong[i].x*tong[i+1].y-tong[i].y*tong[i+1].x;
        if(sum>0) return sum/2;
        else return -sum/2;
    }
    void shifang(int a,int b)
    { 
    	int i,ll,N;N=F[a].size();
        for(i=0;i<N;i++)
    	{    ll=F[a][i];
    	  if(ll==b) break;
    	}
         F[a].erase(F[a].begin()+i);
    	N=F[b].size();
    	 for(i=0;i<N;i++)
         {
    	     ll=F[b][i];
    		 if(ll==a)
    			 break;
    	 }
    	 F[b].erase(F[b].begin()+i);
    }
    double cross(point a,point b){return a.x*b.y-a.y*b.x;}
    int look(int fa,int now,int nu)
    {
         
    	    if(vis[now]==2&&mark[now]) return nu;
         	tong[nu]=node[now];
      
          point gh[1000],p1=node[now],p2=node[now];
         int a=0,i,nut=0,T=0; bool k1,k2; k1=k2=false;
         if(vis[now]) a=1;
         for(i=0;i<F[now].size();i++)
    	 {   
    		 int ll=F[now][i];
    		 if((vis[ll]==0||a==0)&&mark[ll]&&ll!=fa)
            {
    			 
                 gh[nut++]=node[ll];
            }
    	 }
         for(i=0;i<nut;i++)
                if(cross(node[now]-node[fa],gh[i]-node[fa])>=0)
                {
    				if(cross(gh[i]-node[now],p1-node[now])<0||p1==node[now])
    				{	p1=gh[i];  k1=1;}
    			}                
    			else 
    			{
    				if(p2==node[now]||cross(p2-node[now],gh[i]-node[now])>0)
    				{p2=gh[i]; k2=1; }
    			}
    
         vis[now]=1;
    	 if(!(p1==node[now])||k1)
    	 {    
              int ll=P[p1]  ;                   
    	  	 T=look(now,ll,nu+1);
    	 }
    	 else if(!(p2==node[now])||k2){
    		  int ll=P[p2];
    		 T=look(now,ll,nu+1);
    	 }
         vis[now]=0;
         return T;
    }
    point G;
    bool cmp1(point a,point b)
    {
    	point ll=G;
        return cross(a-ll,b-ll)>=0;
    }
    bool cmp2(point a,point b)
    {
    	return a.y<b.y||(a.y==b.y&&a.x<=b.x);
    }
    void work()
    {
      int k,j,i,T;
    point pp[1500];
        for(i=0;i<sum;i++)
        {
    		G=node[i];
    		int a=P[node[i]];
            vis[a]=2;
              for(k=0;k<F[a].size();k++)
                pp[k]=node[F[a][k]];
    		  sort(pp,pp+k,cmp2);
    		sort(pp,pp+k,cmp1);
            for(j=0;j<k;j++)
            {
                tong[0]=node[a];
    			int gg=P[pp[j]];
                if((T=look(a,gg,1)))
                {
                   A[ct++]=area(T);
    			  // for(int kk=0;kk<T;kk++)
    				//   printf("%.3lf %.3lf    ",tong[kk].x,tong[kk ].y);
    			   //printf("
    
    ");
                }
                shifang(a,gg);
            }
    		vis[a]=1;
            mark[a]=false;
    	}
    }
    int main()
    {
        point t1,t2;
        int i,a,b,f=0;
    	//freopen("data.txt","r",stdin);
        while(scanf("%d",&n)==1)
        {
    
    		if(f)puts("");f=1;
    		 P.clear(); 
            ct=0;
            memset(mark,true,sizeof(mark));memset(num,0,sizeof(num));
            memset(vis,0,sizeof(vis));
            for(i=0;i<1500;i++)
               F[i].clear();
               sum=0;
           for(i=0;i<n;i++)
           {
               scanf("%lf%lf%lf%lf",&L[i].p1.x,&L[i].p1.y,&L[i].p2.x,&L[i].p2.y);
               a=P[L[i].p1];
               b=P[L[i].p2];
               if(a==0)
               {node[sum++]=L[i].p1; a=P[L[i].p1]=sum;}
               if(b==0)
               { node[sum++]=L[i].p2;b=P[L[i].p2]=sum;}
           }
           P.clear();
           sort(node,node+sum,cmp);
           for(i=0;i<sum;i++)
             P[node[i]]=i;
    	   for(i=0;i<n;i++)
    	   {
               a=P[L[i].p1];b=P[L[i].p2];
    		   F[a].push_back(b);
    		   F[b].push_back(a);
    	   }
           work();
    	   sort(A,A+ct);
    	   for(i=0;i<ct;i++)
    		   printf("%.2lf
    ",A[i]);
    	   P.clear();
        }
        return 0;
    }
    
    


     

  • 相关阅读:
    Python实现栈、队列、双端队列
    Redis主从配置、数据持久化、集群
    Redis安装,数据类型及常用命令
    nginx+uwsgi环境部署
    Nginx负载均衡、location匹配
    Nginx安装、多域名访问
    Linux-mysql的备份与恢复
    Linux-mysql主从复制
    Python dumps()的使用
    Python rpush()函数
  • 原文地址:https://www.cnblogs.com/Opaser/p/3662056.html
Copyright © 2011-2022 走看看