Geometric Shapes POJ - 3449 (多个多边形相交)

Geometric Shapes POJ - 3449 

题目链接:https://vjudge.net/problem/POJ-3449

题意:

给你很多图画,每张图画上很多图形,有三角形(给出三个点坐标),正方形(给出对角线两个点坐标),矩形(给出三个点坐标),线段(给出两个点坐标),多边形(给出n个点坐标),还要排序这些图形按照输入的每行首字母排序,与其相交的图形编号(字母)也要排序,然后按规定格式输出

思路:这题不管做法输入输出都极其恶心。。。。细节很多,题意不难理解,枚举所有图形的点,判断每个图形的每条线段与其他所有图形的每条线段是否相交。。。

详解见注释。。

//
// Created by HJYL on 2020/1/21.
//
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
#define eps 1e-8
#define Inf 0x7fffffff
//#include<bits/stdc++.h>
using namespace std;
const int maxn=100;
struct Point{
    double x,y;
};

struct pic{
    Point p[maxn];//图形的每个点
    char id;//图形最前面的字母
    int dot;//图形一共有几个点
    char  jiao[maxn];//图形与哪些图形相交
    bool operator<(pic const &other)const{
        return this->id<other.id;
    }//图形根据字母从小到达排序
};

bool IsSegmentIntersect(Point a, Point b, Point c, Point d)//判断线段是否相交
{
    if( min(a.x, b.x) > max(c.x, d.x) ||
        min(a.y, b.y) > max(c.y, d.y) ||
        min(c.x, d.x) > max(a.x, b.x) ||
        min(c.y, d.y) > max(a.y, b.y) )
        return 0;

    double h, i, j, k;

    h = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
    i = (b.x - a.x) * (d.y - a.y) - (b.y - a.y) * (d.x - a.x);
    j = (d.x - c.x) * (a.y - c.y) - (d.y - c.y) * (a.x - c.x);
    k = (d.x - c.x) * (b.y - c.y) - (d.y - c.y) * (b.x - c.x);

    return h * i <= eps && j * k <= eps;
}

int main()
{
    pic pp[maxn];
    char ch1;
    int pos=0;
    while(cin>>ch1)
    {
        if(ch1=='.')
            break;
        else
        {
            if(ch1=='-')
            {
                //cout<<"pos="<<pos<<endl;
                sort(pp,pp+pos);//按照字母排序
                //cout<<"pppp1"<<endl;
                for(int i=0;i<pos;i++)//枚举每个线段与其他图形是否相交
                {
                    int cnt=-1;
                    // cout<<"gggggg"<<endl;
                    for(int j=0;j<pos;j++)
                    {
                        if(i==j)
                            continue;
                        bool flag=false;
                        //cout<<"pp[i].dot="<<pp[i].dot<<endl;
                        //cout<<"pp[j].dot="<<pp[j].dot<<endl;
                        for(int k=0;k<pp[i].dot-1;k++)
                        {
                            for(int t=0;t<pp[j].dot-1;t++)
                            {
                                if(IsSegmentIntersect(pp[i].p[k],pp[i].p[k+1],pp[j].p[t],pp[j].p[t+1])
                                ||IsSegmentIntersect(pp[i].p[0],pp[i].p[pp[i].dot-1],pp[j].p[t],pp[j].p[t+1])
                                ||IsSegmentIntersect(pp[i].p[0],pp[i].p[pp[i].dot-1],pp[j].p[0],pp[j].p[pp[j].dot-1])
                                ||IsSegmentIntersect(pp[i].p[k],pp[i].p[k+1],pp[j].p[0],pp[j].p[pp[j].dot-1]))//别忘了图形收尾相连的线段,都要判断
                                {
                                    // cout<<"hhhhhhh"<<endl;
                                    pp[i].jiao[++cnt]=pp[j].id;//将字母存入数组
                                    //cout<<pp[i].id<<" "<<pp[j].id<<endl;
                                    //cout<<"cnt="<<cnt<<endl;
                                    flag=true;
                                    break;
                                }
                            }
                            if(flag)
                                break;
                        }
                    }
                    //cout<<"cnt=="<<cnt<<endl;
                    if(cnt==-1)
                    {
                        printf("%c has no intersections\n",pp[i].id);
                        //pos=0;
                    }
                    else{
                        sort(pp[i].jiao,pp[i].jiao+cnt+1);
                        if(cnt==0)
                        {
                            printf("%c intersects with %c\n",pp[i].id,pp[i].jiao[0]);
                        }
                        else if(cnt==1)
                        {
                            printf("%c intersects with %c and %c\n",pp[i].id,pp[i].jiao[0],pp[i].jiao[1]);

                        }
                        else
                        {
                            printf("%c intersects with ",pp[i].id);
                            for(int kk=0;kk<cnt;kk++)
                                printf("%c, ",pp[i].jiao[kk]);
                            printf("and %c\n",pp[i].jiao[cnt]);

                        }
                    }
                }
                printf("\n");
                pos=0;//将别忘了将图画的图形个数更新为0
            }
            else
            {
                char kind[50];
                cin>>kind;
                //cout<<"kind[0]="<<kind[0]<<endl;
                //getchar();//括号前空格
                if(kind[0]=='s')
                {
                    scanf(" (%lf,%lf)",&pp[pos].p[0].x,&pp[pos].p[0].y);//这种输入应该最简便了。。。。
                    scanf(" (%lf,%lf)",&pp[pos].p[2].x,&pp[pos].p[2].y);
                    pp[pos].dot=4;
                    pp[pos].id=ch1;//重点掌握已知正方形对角线两点求剩下两点
                    pp[pos].p[1].x=((pp[pos].p[0].x+pp[pos].p[2].x)+(pp[pos].p[2].y-pp[pos].p[0].y))/2;
                    pp[pos].p[1].y=((pp[pos].p[0].y+pp[pos].p[2].y)+(pp[pos].p[0].x-pp[pos].p[2].x))/2;
                    pp[pos].p[3].x=((pp[pos].p[0].x+pp[pos].p[2].x)-(pp[pos].p[2].y-pp[pos].p[0].y))/2;
                    pp[pos].p[3].y=((pp[pos].p[0].y+pp[pos].p[2].y)-(pp[pos].p[0].x-pp[pos].p[2].x))/2;
                    pos++;
                }
                else if(kind[0]=='r')
                {
                    scanf(" (%lf,%lf)",&pp[pos].p[0].x,&pp[pos].p[0].y);
                    scanf(" (%lf,%lf)",&pp[pos].p[1].x,&pp[pos].p[1].y);
                    scanf(" (%lf,%lf)",&pp[pos].p[2].x,&pp[pos].p[2].y);
                    pp[pos].id=ch1;
                    pp[pos].dot=4;//已知矩形三个点求最后一点坐标
                    pp[pos].p[3].x=pp[pos].p[2].x + (pp[pos].p[0].x - pp[pos].p[1].x);
                    pp[pos].p[3].y=pp[pos].p[2].y + (pp[pos].p[0].y - pp[pos].p[1].y);
                    pos++;
                }
                else if(kind[0]=='l')
                {
                    scanf(" (%lf,%lf)",&pp[pos].p[0].x,&pp[pos].p[0].y);
                    scanf(" (%lf,%lf)",&pp[pos].p[1].x,&pp[pos].p[1].y);
                    pp[pos].id=ch1;
                    pp[pos].dot=2;
                    pos++;
                }
                else if(kind[0]=='t')
                {
                    scanf(" (%lf,%lf)",&pp[pos].p[0].x,&pp[pos].p[0].y);
                    scanf(" (%lf,%lf)",&pp[pos].p[1].x,&pp[pos].p[1].y);
                    scanf(" (%lf,%lf)",&pp[pos].p[2].x,&pp[pos].p[2].y);
                    pp[pos].id=ch1;
                    pp[pos].dot=3;
                    pos++;
                }
                else if(kind[0]=='p')
                {
                    int t;
                    cin>>t;//多边形
                    char kuo;int x,y;
                    for(int i=0;i<t;i++)
                    {
                        scanf(" (%lf,%lf)",&pp[pos].p[i].x,&pp[pos].p[i].y);
                    }
                    pp[pos].id=ch1;
                    pp[pos].dot=t;
                    pos++;
                }
            }
        }
    }
    return 0;
}
posted @ 2020-01-21 23:22  branna  阅读(199)  评论(0编辑  收藏  举报