| ||||||||||
Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
关于题意和算法上面的一些注意点+代码1. 所谓相交,不包括一个图形在另一个里面的情况,即仅只有线段相交才算 2. 对于任意两个线段,在本题中,只要是有任意公共点即当作相交 3. 代码比较长,注意细节 4. 对于点对的读入,可以用下面的方法来快速读入: scanf(" (%lf,%lf)",&x,&y); 注意: ↑这里有一个空格!! 5. 处理和输出前,图形要按照编号排序 6. 编号只有单个大写字母 7. 这里正方形可以采用计算中点+(初中数学基本模型)一线三等角来计算, 具体公式见代码 8. 长方形的三个点是连续的3个点(一开始我还以为是任意的,还写了根据最 长边swap的代码(可惜写错了,导致了一次wa),其实不用),计算第四个 点就可以采用对应点平移的方法,具体公式见代码 代码: #include <cstring> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cmath> #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define sqr(a) ((a)*(a)) using namespace std; const double Eps=1e-8; struct Point{ double x,y; void read(){ scanf(" (%lf,%lf)",&x,&y); } }; struct Line{ Point a,b; void build(Point a_,Point b_){ a=a_,b=b_; } }; struct Polygon{ char bh;//编号 int n,e;//n为点数,e为边数 Point P[20+5];//存点 Line L[20+5];//存边 void buildL(){//根据点的信息建立相应的边(线段) if (n==2){ e=1; L[1].build(P[1],P[2]); return; } e=n; for (int i=1;i<n;i++) L[i].build(P[i],P[i+1]); L[n].build(P[n],P[1]); } }p[26+5]; double Cross(Point a,Point b,Point c){ return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); } bool FCross(Point a,Point b,Point c){ return Cross(a,b,c)<0; } bool BeInTwoSide(Line a,Line b){ if (fabs(Cross(a.a,a.b,b.a))<Eps||fabs(Cross(a.a,a.b,b.b))<Eps) return 1; return FCross(a.a,a.b,b.a)^FCross(a.a,a.b,b.b); } bool LCrossEachOther(Line a,Line b){//判断两个线段是否相交 if (fabs(Cross(a.a,b.a,a.b))<Eps&&fabs(Cross(a.a,b.b,a.b))<Eps&& fabs(Cross(b.a,a.a,b.b))<Eps&&fabs(Cross(b.a,a.b,b.b))<Eps) { if (fabs(a.a.x-a.b.x)<Eps){ return (min(a.a.y,a.b.y)<=b.a.y&&b.a.y<=max(a.a.y,a.b.y))|| (min(a.a.y,a.b.y)<=b.b.y&&b.b.y<=max(a.a.y,a.b.y)); } else { return (min(a.a.x,a.b.x)<=b.a.x&&b.a.x<=max(a.a.x,a.b.x))|| (min(a.a.x,a.b.x)<=b.b.x&&b.b.x<=max(a.a.x,a.b.x)); } } return BeInTwoSide(a,b)&&BeInTwoSide(b,a); } bool PCrossEachOther(Polygon a,Polygon b){//判断两个图形是否相交 for (int i=1;i<=a.e;i++) for (int j=1;j<=b.e;j++) if (LCrossEachOther(a.L[i],b.L[j])) return 1; return 0; } bool PolygonBhCmp(Polygon a,Polygon b){//用于图形标号排序 return a.bh<b.bh; } int n; char str[15]; int main(){ while (1){ n=0; while (1){ n++; scanf("%s",str); if (n==1&&str[0]=='.') return 0; if (str[0]=='-'){ n--; break; } p[n].bh=str[0]; scanf("%s",str); if (str[0]=='s'){//正方形 Point a,b,c,d,mid; a.read(),c.read(); mid.x=(a.x+c.x)/2; mid.y=(a.y+c.y)/2; b.x=mid.x+a.y-mid.y; b.y=mid.y-a.x+mid.x; d.x=mid.x*2-b.x; d.y=mid.y*2-b.y; p[n].n=4; p[n].P[1]=a,p[n].P[2]=b,p[n].P[3]=c,p[n].P[4]=d; } if (str[0]=='r'){//矩形 Point a,b,c,d; a.read(),b.read(),c.read(); d.x=c.x+a.x-b.x; d.y=c.y+a.y-b.y; p[n].n=4; p[n].P[1]=a,p[n].P[2]=b,p[n].P[3]=c,p[n].P[4]=d; } if (str[0]=='l'){//线段 p[n].n=2; p[n].P[1].read(),p[n].P[2].read(); } if (str[0]=='t'){//三角形 p[n].n=3; p[n].P[1].read(),p[n].P[2].read(),p[n].P[3].read(); } if (str[0]=='p'){//多边形 scanf("%d",&p[n].n); for (int i=1;i<=p[n].n;i++) p[n].P[i].read(); } p[n].buildL(); } sort(p+1,p+n+1,PolygonBhCmp); for (int i=1;i<=n;i++){ int cnt=0; char ans[26+5]; for (int j=1;j<=n;j++){ if (j==i) continue; if (PCrossEachOther(p[i],p[j])) ans[++cnt]=p[j].bh; } printf("%c ",p[i].bh); if (cnt==0) puts("has no intersections"); else { printf("intersects with "); if (cnt==1) printf("%c\n",ans[1]); else if (cnt==2) printf("%c and %c\n",ans[1],ans[2]); else { for (int k=1;k<cnt;k++) printf("%c, ",ans[k]); printf("and %c\n",ans[cnt]); } } } puts(""); } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator