Geometric Shapes POJ - 3449 (多个多边形相交)
Geometric Shapes POJ - 3449
题目链接:https://vjudge.net/problem/POJ-3449
题意:
给你很多图画,每张图画上很多图形,有三角形(给出三个点坐标),正方形(给出对角线两个点坐标),矩形(给出三个点坐标),线段(给出两个点坐标),多边形(给出n个点坐标),还要排序这些图形按照输入的每行首字母排序,与其相交的图形编号(字母)也要排序,然后按规定格式输出
思路:这题不管做法输入输出都极其恶心。。。。细节很多,题意不难理解,枚举所有图形的点,判断每个图形的每条线段与其他所有图形的每条线段是否相交。。。
详解见注释。。
// // Created by HJYL on 2020/1/21. // #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<cmath> #define eps 1e-8 #define Inf 0x7fffffff //#include<bits/stdc++.h> using namespace std; const int maxn=100; struct Point{ double x,y; }; struct pic{ Point p[maxn];//图形的每个点 char id;//图形最前面的字母 int dot;//图形一共有几个点 char jiao[maxn];//图形与哪些图形相交 bool operator<(pic const &other)const{ return this->id<other.id; }//图形根据字母从小到达排序 }; bool IsSegmentIntersect(Point a, Point b, Point c, Point d)//判断线段是否相交 { if( min(a.x, b.x) > max(c.x, d.x) || min(a.y, b.y) > max(c.y, d.y) || min(c.x, d.x) > max(a.x, b.x) || min(c.y, d.y) > max(a.y, b.y) ) return 0; double h, i, j, k; h = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); i = (b.x - a.x) * (d.y - a.y) - (b.y - a.y) * (d.x - a.x); j = (d.x - c.x) * (a.y - c.y) - (d.y - c.y) * (a.x - c.x); k = (d.x - c.x) * (b.y - c.y) - (d.y - c.y) * (b.x - c.x); return h * i <= eps && j * k <= eps; } int main() { pic pp[maxn]; char ch1; int pos=0; while(cin>>ch1) { if(ch1=='.') break; else { if(ch1=='-') { //cout<<"pos="<<pos<<endl; sort(pp,pp+pos);//按照字母排序 //cout<<"pppp1"<<endl; for(int i=0;i<pos;i++)//枚举每个线段与其他图形是否相交 { int cnt=-1; // cout<<"gggggg"<<endl; for(int j=0;j<pos;j++) { if(i==j) continue; bool flag=false; //cout<<"pp[i].dot="<<pp[i].dot<<endl; //cout<<"pp[j].dot="<<pp[j].dot<<endl; for(int k=0;k<pp[i].dot-1;k++) { for(int t=0;t<pp[j].dot-1;t++) { if(IsSegmentIntersect(pp[i].p[k],pp[i].p[k+1],pp[j].p[t],pp[j].p[t+1]) ||IsSegmentIntersect(pp[i].p[0],pp[i].p[pp[i].dot-1],pp[j].p[t],pp[j].p[t+1]) ||IsSegmentIntersect(pp[i].p[0],pp[i].p[pp[i].dot-1],pp[j].p[0],pp[j].p[pp[j].dot-1]) ||IsSegmentIntersect(pp[i].p[k],pp[i].p[k+1],pp[j].p[0],pp[j].p[pp[j].dot-1]))//别忘了图形收尾相连的线段,都要判断 { // cout<<"hhhhhhh"<<endl; pp[i].jiao[++cnt]=pp[j].id;//将字母存入数组 //cout<<pp[i].id<<" "<<pp[j].id<<endl; //cout<<"cnt="<<cnt<<endl; flag=true; break; } } if(flag) break; } } //cout<<"cnt=="<<cnt<<endl; if(cnt==-1) { printf("%c has no intersections\n",pp[i].id); //pos=0; } else{ sort(pp[i].jiao,pp[i].jiao+cnt+1); if(cnt==0) { printf("%c intersects with %c\n",pp[i].id,pp[i].jiao[0]); } else if(cnt==1) { printf("%c intersects with %c and %c\n",pp[i].id,pp[i].jiao[0],pp[i].jiao[1]); } else { printf("%c intersects with ",pp[i].id); for(int kk=0;kk<cnt;kk++) printf("%c, ",pp[i].jiao[kk]); printf("and %c\n",pp[i].jiao[cnt]); } } } printf("\n"); pos=0;//将别忘了将图画的图形个数更新为0 } else { char kind[50]; cin>>kind; //cout<<"kind[0]="<<kind[0]<<endl; //getchar();//括号前空格 if(kind[0]=='s') { scanf(" (%lf,%lf)",&pp[pos].p[0].x,&pp[pos].p[0].y);//这种输入应该最简便了。。。。 scanf(" (%lf,%lf)",&pp[pos].p[2].x,&pp[pos].p[2].y); pp[pos].dot=4; pp[pos].id=ch1;//重点掌握已知正方形对角线两点求剩下两点 pp[pos].p[1].x=((pp[pos].p[0].x+pp[pos].p[2].x)+(pp[pos].p[2].y-pp[pos].p[0].y))/2; pp[pos].p[1].y=((pp[pos].p[0].y+pp[pos].p[2].y)+(pp[pos].p[0].x-pp[pos].p[2].x))/2; pp[pos].p[3].x=((pp[pos].p[0].x+pp[pos].p[2].x)-(pp[pos].p[2].y-pp[pos].p[0].y))/2; pp[pos].p[3].y=((pp[pos].p[0].y+pp[pos].p[2].y)-(pp[pos].p[0].x-pp[pos].p[2].x))/2; pos++; } else if(kind[0]=='r') { scanf(" (%lf,%lf)",&pp[pos].p[0].x,&pp[pos].p[0].y); scanf(" (%lf,%lf)",&pp[pos].p[1].x,&pp[pos].p[1].y); scanf(" (%lf,%lf)",&pp[pos].p[2].x,&pp[pos].p[2].y); pp[pos].id=ch1; pp[pos].dot=4;//已知矩形三个点求最后一点坐标 pp[pos].p[3].x=pp[pos].p[2].x + (pp[pos].p[0].x - pp[pos].p[1].x); pp[pos].p[3].y=pp[pos].p[2].y + (pp[pos].p[0].y - pp[pos].p[1].y); pos++; } else if(kind[0]=='l') { scanf(" (%lf,%lf)",&pp[pos].p[0].x,&pp[pos].p[0].y); scanf(" (%lf,%lf)",&pp[pos].p[1].x,&pp[pos].p[1].y); pp[pos].id=ch1; pp[pos].dot=2; pos++; } else if(kind[0]=='t') { scanf(" (%lf,%lf)",&pp[pos].p[0].x,&pp[pos].p[0].y); scanf(" (%lf,%lf)",&pp[pos].p[1].x,&pp[pos].p[1].y); scanf(" (%lf,%lf)",&pp[pos].p[2].x,&pp[pos].p[2].y); pp[pos].id=ch1; pp[pos].dot=3; pos++; } else if(kind[0]=='p') { int t; cin>>t;//多边形 char kuo;int x,y; for(int i=0;i<t;i++) { scanf(" (%lf,%lf)",&pp[pos].p[i].x,&pp[pos].p[i].y); } pp[pos].id=ch1; pp[pos].dot=t; pos++; } } } } return 0; }