您的位置:首页 > 其它

POJ 3449 Geometric Shapes【计算几何+判线段相交】

2017-09-04 14:29 459 查看
题目链接

题意:有一堆多边形,问每个多边形和哪些其他多边形相交。

讲道理是个水题……就是输入输出麻烦了点,中间判下线段相交就行。

线段相交的模板:

// 判断一个数是否为0
bool zero(double x){
if (fabs(x)<eps)    return true;
else    return false;
}

// 求矢量p0->p1, p0->p2的叉积
double xmult(Point p1,Point p2,Point p0){
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}

// 判点是否在线段上,包括端点
int dot_online_in(Point p,Line l){
return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps;
}

//判两点在线段同侧,点在线段上返回0
int same_side(Point p1,Point p2,Line l){
return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;
}

// 判两点在线段异侧
int opposite_side(Point p1,Point p2,Line l){
return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;
}

// 判线段相交,包括端点和部分重合
int intersect_in(Line u,Line v){
if (!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))
return !same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);
return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u);
}

// 判线段相交,不包括端点和部分重合
int intersect_ex(Line u,Line v){
return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define ll long long
#define zero(x) (((x)>0?(x):-(x))<eps)
const double eps=1e-8;

char ch;

struct Point{
double x,y;
};

struct Shape{
string kind;
int n;
Point point[30];
int cnt;
int intersect[30];
}shape[30];

bool vis[30];

double xmult(Point p1,Point p2,Point p0){
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}

int dots_inline(Point p1,Point p2,Point p3){
return zero(xmult(p1,p2,p3));
}

int dot_online_in(Point p,Point p1,Point p2){
return zero(xmult(p,p1,p2))&&(p1.x-p.x)*(p2.x-p.x)<eps&&(p1.y-p.y)*(p2.y-p.y)<eps;
}

int same_side(Point p1,Point p2,Point p3,Point p4){
return xmult(p3,p1,p4)*xmult(p3,p2,p4)>eps;
}

int intersect_in(Point p1,Point p2,Point p3,Point p4){
if (!dots_inline(p1,p2,p3)||!dots_inline(p1,p2,p4))
return !same_side(p1,p2,p3,p4)&&!same_side(p3,p4,p1,p2);
return dot_online_in(p1,p3,p4)||dot_online_in(p2,p3,p4)||dot_online_in(p3,p1,p2)||dot_online_in(p4,p1,p2);
}

void input(int id,string ss){
if (ss=="square"){
shape[id].n=4;
getchar();
scanf("%lf,%lf",&shape[id].point[1].x,&shape[id].point[1].y);
getchar();
getchar();
getchar();
scanf("%lf,%lf",&shape[id].point[3].x,&shape[id].point[3].y);
getchar();
getchar();
double x1,y1,x2,y2,x3,y3,x4,y4;
x1=shape[id].point[1].x;
y1=shape[id].point[1].y;
x3=shape[id].point[3].x;
y3=shape[id].point[3].y;
x2=(x1+x3+y3-y1)/2;
x4=(x1+x3+y1-y3)/2;
y2=(y1+y3+x1-x3)/2;
y4=(y1+y3-x1+x3)/2;
shape[id].point[2].x=x2;
shape[id].point[2].y=y2;
shape[id].point[4].x=x4;
shape[id].point[4].y=y4;
shape[id].point[shape[id].n+1]=shape[id].point[1];
}
else if (ss=="rectangle"){
shape[id].n=4;
for (int i=1;i<=3;i++){
getchar();
scanf("%lf,%lf",&shape[id].point[i].x,&shape[id].point[i].y);
getchar();
getchar();
}
shape[id].point[4].x=shape[id].point[3].x+shape[id].point[1].x-shape[id].point[2].x;
shape[id].point[4].y=shape[id].point[3].y+shape[id].point[1].y-shape[id].point[2].y;
shape[id].point[shape[id].n+1]=shape[id].point[1];
}
else if (ss=="line"){
shape[id].n=2;
for (int i=1;i<=2;i++){
getchar();
scanf("%lf,%lf",&shape[id].point[i].x,&shape[id].point[i].y);
getchar();
getchar();
}
shape[id].point[shape[id].n+1]=shape[id].point[1];
}
else if (ss=="triangle"){
shape[id].n=3;
for (int i=1;i<=3;i++){
getchar();
scanf("%lf,%lf",&shape[id].point[i].x,&shape[id].point[i].y);
getchar();
getchar();
}
shape[id].point[shape[id].n+1]=shape[id].point[1];
}
else if (ss=="polygon"){
scanf("%d",&shape[id].n);
getchar();
for (int i=1;i<=shape[id].n;i++){
getchar();
scanf("%lf,%lf",&shape[id].point[i].x,&shape[id].point[i].y);
getchar();
getchar();
}
shape[id].point[shape[id].n+1]=shape[id].point[1];
}
}

int main(){
// freopen("1.txt","r",stdin);
while (scanf("%c",&ch)!=EOF){
getchar();
memset(vis,false,sizeof(vis));
for (int i=0;i<26;i++){
shape[i].cnt=0;
memset(shape[i].intersect,0,sizeof(shape[i].intersect));
}
if (ch=='.')    break;
string ss;
cin>>ss;
int id=ch-'A';
shape[id].kind=ss;
vis[id]=true;
getchar();
input(id,ss);
while (scanf("%c",&ch)!=EOF){
getchar();
if (ch=='-')    break;
id=ch-'A';
cin>>ss;
shape[id].kind=ss;
getchar();
vis[id]=true;
input(id,ss);
}
for (int i=0;i<26;i++){
if (!vis[i])    continue;
for (int j=i+1;j<26;j++){
if (!vis[j])    continue;
bool flag=false;
for (int k1=1;k1<=shape[i].n;k1++){
for (int k2=1;k2<=shape[j].n;k2++){
if (intersect_in(shape[i].point[k1],shape[i].point[k1+1],shape[j].point[k2],shape[j].point[k2+1])){
flag=true;
break;
}
}
if (flag)
break;
}
if (flag){
shape[i].intersect[++shape[i].cnt]=j;
shape[j].intersect[++shape[j].cnt]=i;
}
}
}
for (int i=0;i<26;i++){
if (!vis[i])    continue;
if (shape[i].cnt==0){
printf("%c has no intersections\n",i+'A');
continue;
}
if (shape[i].cnt==1){
printf("%c intersects with %c\n",i+'A',shape[i].intersect[1]+'A');
continue;
}
if (shape[i].cnt==2){
if (shape[i].intersect[1]>shape[i].intersect[2])
swap(shape[i].intersect[1],shape[i].intersect[2]);
printf("%c intersects with %c and %c\n",i+'A',shape[i].intersect[1]+'A',shape[i].intersect[2]+'A');
continue;
}
sort(shape[i].intersect+1,shape[i].intersect+shape[i].cnt+1);
printf("%c intersects with ",i+'A');
for (int j=1;j<=shape[i].cnt;j++){
// B intersects with S, W, and X
if (j==shape[i].cnt){
printf("and %c\n",shape[i].intersect[j]+'A');
}
else{
printf("%c, ",shape[i].intersect[j]+'A');
}
}
}
putchar('\n');
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj