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;
    }
    
    


     

  • 相关阅读:
    LeetCode 326. Power of Three
    LeetCode 324. Wiggle Sort II
    LeetCode 322. Coin Change
    LeetCode 321. Create Maximum Number
    LeetCode 319. Bulb Switcher
    LeetCode 318. Maximum Product of Word Lengths
    LeetCode 310. Minimum Height Trees (DFS)
    个人站点大开发!--起始篇
    LeetCode 313. Super Ugly Number
    LeetCode 309. Best Time to Buy and Sell Stock with Cooldown (DP)
  • 原文地址:https://www.cnblogs.com/Opaser/p/3662056.html
Copyright © 2011-2022 走看看