题目来源:http://poj.org/problem?id=3449
1:给定一个正方形 对角的坐标 (x0 ,y0), (x2,y2), 求出另2个点(x1,y1), (x3,y3)的坐标公式。(x1,y1)(x3,y3) 坐标可交换,不影响结果
x0+x2 = x1+x3
y0+ y2 = y1+y3
y2-y0 = x3 -x1
x2-x0 = y1-y3
x1 = (x0 + x2 -y2 + y0)/2
y1= (y0 + y2 + x2 -x0)/2
x3=(x0 + x2 + y2 -y0) /2
y3=(y0+y2 -x2 +x0) /2
2:判断几何体相交, 等价于 判断几何体的每条线段 与 另一个几何体的每条线段枚举
3:这题 没有考虑 误差 ,也AC, 可以写一个 考虑误差的版本
4:输入输出过分恶心
5: 排序, 对几何体名称进行排序,后,每次从小到大进行 匹配, 每次都是先匹配小的,然后可以实现从小到大的输出
代码如下:
#include <iostream> #include <algorithm> #include <stdlib.h> #include <stack> #include <iostream> #include <stdio.h> #include <string> #include <string.h> #include <algorithm> #include <stdlib.h> #include <vector> #include <set> #include <math.h> #include <cmath> #include <map> #include <stack> #include <queue> #define max(a,b) ( (a) > (b) ? (a) : (b)) #define min( a,b ) ( (a) < (b) ? (a) : (b) ) using namespace std ; typedef long long LL ; struct Point { double x,y; Point(){} Point(double x,double y):x(x),y(y){} Point operator -(Point p) { return Point(x-p.x , y- p.y); } Point operator +( Point p) { return Point( x + p.x , y + p.y); } double operator^(Point p){ return x* p.y - y*p.x; } bool operator == (Point p) { return (x==p.x) && (y==p.y); } }; struct data // 为每个几何体建一个数据结构 { int n,m; // n 表示 几何体的边数, m,表示 相交几何体的数量。 char c, name[30] ; // c表示几何体的名称, name 表示各个相交几何体的名称。 Point p[25]; // p为几何体的各个顶点 bool operator <( const data &d)const { return c<d.c; } void read() { printf("c=%c, n=%d, m=%d, name=%s ", c,n,m,name); } }sha[30]; // 判断点p0是否在线段 p1p2内 int on_segment(Point p1, Point p2, Point p0) { if( (p1-p0).x * ( p2-p0).x <= 0 && (p1-p0).y * (p2-p0).y <= 0 ) return 1; return 0; } // 判断 线段p1p2与q1q2是否相交 int intersection( Point p1, Point p2, Point q1, Point q2) { double d1= (p2-p1)^(q1- p1); double d2= (p2-p1)^(q2-p1); double d3= (q2-q1)^(p1-q1); double d4= (q2 - q1)^(p2 - q1); if( (d1==0 && on_segment(p1,p2,q1) ) || ( d2==0 && on_segment( p1,p2,q2) ) || (d3==0 && on_segment( q1,q2,p1)) || ( d4==0 && on_segment(q1,q2,p2) ) ) return 1; if( d1 * d2 < 0 && d3* d4 <0) return 1; return 0; } // 判断几何体 a 与几何体 b 是否相交 bool index(int a,int b) { int i,j; for(i=0; i<sha[a].n; i++) { for(j=0 ; j<sha[b].n ;j++) { if( intersection( sha[a].p[i] , sha[a].p[(i+1) % sha[a].n], sha[b].p[j], sha[b].p[ (j+1) % sha[b].n ] ) ) return 1; } } return 0; } // 已知正方形的(x0,y0)(x2,y2) 求(x1,y1)(x3,y3)的坐标 void square(int i) { sha[i].n=4; sha[i].p[2].x=sha[i].p[1].x; sha[i].p[2].y=sha[i].p[1].y; double x0,y0,x2,y2; x0= sha[i].p[0].x; y0= sha[i].p[0].y; x2= sha[i].p[2].x; y2= sha[i].p[2].y; sha[i].p[1].x= (x0+ x2 + y2 - y0) / 2.0; sha[i].p[1].y=( y0 + y2 -x2 +x0 ) / 2.0; sha[i].p[3].x=(x0+ x2 -y2 + y0) / 2.0; sha[i].p[3].y = (y0 + y2 +x2 - x0) / 2.0; } //已知矩形 (x0,y0)(x1,y1),(x2,y2)求(x3,y3) void rec(int i) { sha[i].n=4; sha[i].p[3]= sha[i].p[0] + sha[i].p[2]-sha[i].p[1]; } int main(){ char str[15]; while(1) { int i=0; while( 1 ) { scanf("%s",str); if (str[0] == '-' || str[0] == '.') break; sha[i].c=str[0]; scanf("%s",str); if(str[0] == 's' || str[0] == 'l') sha[i].n=2; else if(str[0] == 'r' || str[0] == 't') sha[i].n=3; else scanf("%d",&sha[i].n); for(int j=0; j<sha[i].n; j++) { scanf(" (%lf,%lf)",&sha[i].p[j].x,&sha[i].p[j].y); // 格式控制输入 } if(str[0] == 's') square(i); else if(str[0] == 'r') rec(i); sha[i].m=0; i++; } if(str[0] == '.') break; int len =i; sort(sha,sha+len); // 排序 for(int j=0; j<len ;j++) // 几何体匹配 { for(int k = j+1 ; k< len ; k++) { if(index( j, k )) { sha[j].name[sha[j].m ++ ] = sha[k].c; sha[k].name[sha[k].m++ ] = sha[j].c; } } } for(int j=0 ;j<len ; j++) // 输出 { printf("%c ",sha[j].c); if(sha[j].m==0) printf("has no intersections "); else { printf("intersects with "); if(sha[j].m==1) printf("%c ",sha[j].name[0]); else if( sha [j].m == 2) printf("%c and %c ",sha[j].name[0],sha[j].name[1]); else { int k; for( k=0 ; k< sha[j].m -1 ;k++) printf("%c, ",sha[j].name[k] ); printf("and %c ",sha[j].name[k]); } } } printf(" "); } return 0 ; }