poj 3449 Geometric Shapes

求各种图形的相交问题,简化到求线段相交问题。

WA了一次,原因是叉积相乘超出了int范围,以后要注意!

 

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
char str[30][3], ans[30];
int n;
struct Point{
    int x, y;
    Point operator +(Point p1)const{
        p1.x+=x;p1.y+=y;
        return p1;
    }
    Point operator -(Point p1)const{
        p1.x=x-p1.x;p1.y=y-p1.y;
        return p1;
    }
};
struct Segline{Point s, e;};
struct node{
    char name;
    int cnt;
    Point p[25];
}a[30];

Point getpoint(){
    char ss[20];
    Point pt;
    scanf("%s", ss);
    sscanf(ss, "%*c%d%*c%d%*c", &pt.x, &pt.y);
    return pt;
}

void read(){
    a[n].name=str[n][0];
    char ss[20];
    scanf("%s", ss);
    if(strcmp(ss, "square")==0){
        a[n].cnt=4;
        a[n].p[0]=getpoint();
        a[n].p[2]=getpoint();
        a[n].p[1].x=(a[n].p[0].x+a[n].p[2].x+a[n].p[2].y-a[n].p[0].y)/2;
        a[n].p[1].y=(a[n].p[0].y+a[n].p[2].y+a[n].p[0].x-a[n].p[2].x)/2;
        a[n].p[3].x=(a[n].p[0].x+a[n].p[2].x-a[n].p[2].y+a[n].p[0].y)/2;
        a[n].p[3].y=(a[n].p[0].y+a[n].p[2].y-a[n].p[0].x+a[n].p[2].x)/2;
    }
    else if(strcmp(ss, "rectangle")==0){
        a[n].cnt=4;
        a[n].p[0]=getpoint();
        a[n].p[1]=getpoint();
        a[n].p[2]=getpoint();
        a[n].p[3]=a[n].p[0]+a[n].p[2]-a[n].p[1];
    }
    else if(strcmp(ss, "line")==0){
        a[n].cnt=2;
        a[n].p[0]=getpoint();
        a[n].p[1]=getpoint();
    }
    else if(strcmp(ss, "triangle")==0){
        a[n].cnt=3;
        a[n].p[0]=getpoint();
        a[n].p[1]=getpoint();
        a[n].p[2]=getpoint();
    }
    else if(strcmp(ss, "polygon")==0){
        scanf("%d", &a[n].cnt);
        for(int i=0; i<a[n].cnt; i++)
        a[n].p[i]=getpoint();
    }
}

void init(){
    read();
    n=1;
    while(scanf("%s", str[n])&&str[n][0]!='-'){
        read();
        n++;
    }
}

bool cmp(node a1, node a2){
    return a1.name<a2.name;
}

long long x_mult(Point sp, Point ep, Point op){
    return (long long)(sp.x-op.x)*(ep.y-op.y)-(long long)(sp.y-op.y)*(ep.x-op.x);
}

bool online(Point p1, Point p2, Point p3, Point p4){
    if(max(p1.x,p2.x)<min(p3.x,p4.x)||max(p1.y,p2.y)<min(p3.y, p4.y)||
       min(p1.x,p2.x)>max(p3.x,p4.x)||min(p1.y,p2.y)>max(p3.y, p4.y))
       return false;
       return true;
}
bool x_segline(Segline s1, Segline s2){
    if(online(s1.s,s1.e,s2.s,s2.e)&& x_mult(s1.e, s2.s, s1.s)*x_mult(s1.e, s2.e, s1.s)<=0&&
        x_mult(s2.e, s1.s, s2.s)*x_mult(s2.e, s1.e, s2.s)<=0)
            return true;
        return false;
}

bool check(node a1, node a2){
    Segline seg1, seg2;
    a1.p[a1.cnt]=a1.p[0];a2.p[a2.cnt]=a2.p[0];
    for(int i=0; i<a1.cnt; i++){
        seg1.s=a1.p[i];seg1.e=a1.p[i+1];
        for(int j=0; j<a2.cnt; j++){
            seg2.s=a2.p[j];seg2.e=a2.p[j+1];
            if(x_segline(seg1, seg2))
                return true;
        }
    }
    return false;
}

void solve(){
    sort(a, a+n, cmp);
    for(int i=0; i<n; i++){
        int res=0;
        for(int j=0; j<n; j++){
            if(j==i)continue;
            if(check(a[i], a[j])){
                ans[res++]=a[j].name;
            }
        }
        if(res==0)
            printf("%c has no intersections\n", a[i].name);
        else if(res==1)
            printf("%c intersects with %c\n", a[i].name, ans[0]);
        else if(res==2)
            printf("%c intersects with %c and %c\n", a[i].name, ans[0], ans[1]);
        else {
            printf("%c intersects with ", a[i].name);
            for(int k=0; k<res-1; k++)
            printf("%c, ", ans[k]);
            printf("and %c\n", ans[res-1]);
        }
    }
    printf("\n");
}

int main(){
    //freopen("1.txt", "r", stdin);
    n=0;
    while(scanf("%s", str[0])&&str[0][0]!='.'){
        init();
        solve();
        n=0;
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值