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("\n\n"); } 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\n",A[i]); P.clear(); } return 0; }