POJ 3449 Geometric Shapes (线段相交)

题意:给你多种形状的图形,问那些图形是相交的(线段相交),

思路:暴力判断线段相交

以前交了18遍都不过,现在重新写了一遍,不懂怎么了就过了。。郁闷啊。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;
const double EPS = 1e-6;
const double INF = 1e20;
struct cvector{
    double x,y;
    cvector(double a,double b){x=a,y=b;}
    cvector(){}
};
cvector operator-(cvector a,cvector b){
    return cvector(a.x-b.x,a.y-b.y);
}
cvector operator+(cvector a,cvector b){
    return cvector(a.x+b.x,a.y+b.y);
}
cvector operator*(double a,cvector b){
    return cvector(a*b.x,a*b.y);
}
double operator*(cvector a,cvector b){
    return a.x*b.y+b.x*a.y;
}
double operator^(cvector a,cvector b){
    return a.x*b.y-b.x*a.y;
}
double length(double t){return t<0?-t:t;}
double length(cvector t){return sqrt(t*t);}
struct cpoint{
    double x,y;
    cpoint(double a,double b){x=a,y=b;}
    cpoint(){}
};
cvector operator-(cpoint a,cpoint b){
    return cvector(a.x-b.x,a.y-b.y);
}
cpoint operator+(cpoint a,cvector b){
    return cpoint(a.x+b.x,a.y+b.y);
}
struct cline{
    cpoint a,b;
    cline(cpoint x,cpoint y){a=x,b=y;}
    cline(){}
};
bool online(cline a,cline b){
    if(max(a.a.x,a.b.x)<min(b.a.x,b.b.x)||max(a.a.y,a.b.y)<min(b.a.y,b.b.y)||
       min(a.a.x,a.b.x)>max(b.a.x,b.b.x)||min(a.a.y,a.b.y)>max(b.a.y,b.b.y))
       return false;
    return true;
}
bool intersect(cline a,cline b){
    return online(a,b)&&((a.a-b.a)^(b.b-b.a))*((a.b-b.a)^(b.b-b.a))<EPS&&
    ((b.a-a.a)^(a.b-a.a))*((b.b-a.a)^(a.b-a.a))<EPS;
}
struct node{
    cpoint pp[29];
    char num;
    int n;
    bool v[59];
    int ans[59],an;
    void init(){memset(v,false,sizeof(v));an=0;}
    bool operator<(const node t)const{
        return num<t.num;
    }
} re[59];
char in[50];
void in_square(int cnt)
{
    re[cnt].n=4;
    scanf("%s",in);
    sscanf(in,"(%lf,%lf)",&re[cnt].pp[0].x,&re[cnt].pp[0].y);
    re[cnt].pp[4] = re[cnt].pp[0];
    scanf("%s",in);
    sscanf(in,"(%lf,%lf)",&re[cnt].pp[2].x,&re[cnt].pp[2].y);
    cpoint center=cpoint((re[cnt].pp[0].x+re[cnt].pp[2].x)/2,(re[cnt].pp[0].y+re[cnt].pp[2].y)/2);
    cvector c = 0.5*(re[cnt].pp[0]-re[cnt].pp[2]);
    c = cvector(c.y,-c.x);
    re[cnt].pp[1] = center+c;
    c = -1.0*c;
    re[cnt].pp[3] = center+c;
}
void in_rectangle(int cnt)
{
    re[cnt].n = 4;
    for(int i=0;i<3;i++)
    {
        scanf("%s",in);
        sscanf(in,"(%lf,%lf)",&re[cnt].pp[i].x,&re[cnt].pp[i].y);
    }
    re[cnt].pp[4] = re[cnt].pp[0];
    re[cnt].pp[3] = re[cnt].pp[0]+(re[cnt].pp[2]-re[cnt].pp[1]);
}
void in_line(int cnt)
{
    re[cnt].n = 1;
    for(int i=0;i<2;i++)
    {
        scanf("%s",in);
        sscanf(in,"(%lf,%lf)",&re[cnt].pp[i].x,&re[cnt].pp[i].y);
    }
}
void in_triangle(int cnt)
{
    re[cnt].n = 3;
    for(int i=0;i<3;i++)
    {
        scanf("%s",in);
        sscanf(in,"(%lf,%lf)",&re[cnt].pp[i].x,&re[cnt].pp[i].y);
    }
    re[cnt].pp[3] = re[cnt].pp[0];
}
void in_polygon(int cnt)
{
    int n;
    scanf("%d",&n);
    re[cnt].n = n;
    for(int i=0;i<n;i++)
    {
        scanf("%s",in);
        sscanf(in,"(%lf,%lf)",&re[cnt].pp[i].x,&re[cnt].pp[i].y);
    }
    re[cnt].pp[n] = re[cnt].pp[0];
}
int main()
{
    freopen("in.txt","r",stdin);
    freopen("ou.txt","w",stdout);
    char nam[5],ch[20];
    while(1)
    {
        int cnt = 0;
        while(1)
        {
            scanf("%s",nam);
            if(nam[0]=='.') return 0;
            if(nam[0]=='-') break;
            re[cnt].num = nam[0];
            re[cnt].init();
            scanf("%s",ch);
            if(strcmp(ch,"square")==0)
            in_square(cnt);
            else if(strcmp(ch,"rectangle")==0)
            in_rectangle(cnt);
            else if(strcmp(ch,"line")==0)
            in_line(cnt);
            else if(strcmp(ch,"triangle")==0)
            in_triangle(cnt);
            else if(strcmp(ch,"polygon")==0)
            in_polygon(cnt);
            cnt++;
        }
        sort(re,re+cnt);
        for(int i=0;i<cnt;i++)
        {
            for(int j=i+1;j<cnt;j++)
            {
                for(int k=0;k<re[i].n;k++)
                for(int l=0;l<re[j].n;l++)
                if(intersect(cline(re[i].pp[k],re[i].pp[k+1]),cline(re[j].pp[l],re[j].pp[l+1])))
                re[i].v[j] = true,re[j].v[i] = true;
            }
        }
        for(int i=0;i<cnt;i++)
        {
            for(int j=0;j<cnt;j++)
            if(re[i].v[j]) re[i].ans[re[i].an++] = j;
        }
        for(int i=0;i<cnt;i++)
        {
            printf("%c ",re[i].num);
            if(re[i].an==0)
            {
                printf("has no intersections\n");
            }else if(re[i].an==1){
                printf("intersects with %c\n",re[re[i].ans[0]].num);
            }else if(re[i].an==2){
                printf("intersects with %c and %c\n",re[re[i].ans[0]].num,re[re[i].ans[1]].num);
            }else{
                printf("intersects with %c",re[re[i].ans[0]].num);
                for(int j=1;j<re[i].an;j++){
                    if(j==re[i].an-1) printf(", and ");
                    else printf(", ");
                    printf("%c",re[re[i].ans[j]].num);
                }
                printf("\n");
            }
        }
        printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值