HDU 1558

输入线段的两个短点,如果线段相交那么他们属于一个集合,查看第i条线段所在的集合有几条线段。

好久没码码了,总是各种蠢。

首先找出两条直线的方程,求解相交点的横坐标,然后看是不是在线段内部。

没有注意题目中从1开始数,我自己写的从0开始数,各种wa。

同时,又受到了杭电的输出大坑(between和fllowed两种不同!!)

#include<iostream>

#include<stdio.h>

using namespace std;

struct po

{

    double lx,ly,rx,ry,k,b;//线段左端点和右端点的坐标,斜率,截距

    bool ok;//ok为1表示斜率存在,否则不存在

};

po me[1005];

int li[1005];

int num[1005];

void init(int a)

{

    int i;

    for(i=0;i<=a;i++)

    {

        li[i]=i;

        num[i]=1;

    }

}

int findme(int a)

{

    if(a!=li[a])

        return li[a]=findme(li[a]);

    return li[a];

}

int main()

{

    int t,i,j,n,k,tmp,w,tmpk,tmpw;

    double tmp1,tmp2,tmp3,tmp4,tmpx;

    char typ;

    while(scanf("%d",&t)!=EOF)

    {

        getchar();

        for(i=1;i<=t;i++)

        {

            scanf("%d",&n);

            init(n);

            getchar();

            k=1;

            for(j=0;j<n;j++)

            {

                scanf("%c",&typ);

                if(typ=='P')

                {

                    scanf("%lf%lf%lf%lf",&tmp1,&tmp2,&tmp3,&tmp4);

                    me[k].ok=1;

                    if(tmp1<tmp3)

                    {

                        me[k].lx=tmp1;

                        me[k].ly=tmp2;

                        me[k].rx=tmp3;

                        me[k].ry=tmp4;

                    }

                    else

                    {

                        me[k].lx=tmp3;

                        me[k].ly=tmp4;

                        me[k].rx=tmp1;

                        me[k].ry=tmp2;

                    }

                    if(me[k].lx==me[k].rx)

                    {

                        me[k].ok=0;

                    }

                    else

                    {

                        me[k].k=(me[k].ly-me[k].ry)/(me[k].lx-me[k].rx);

                        me[k].b=me[k].ly-me[k].k*me[k].lx;

                    }

                    for(w=k-1;w>=1;w--)

                    {

                        tmpk=findme(k);

                        tmpw=findme(w);

                        if(tmpk!=tmpw)

                        {

                            if(me[k].ok&&me[w].ok)

                            {

                                tmpx=(me[k].b-me[w].b)/(me[w].k-me[k].k);

                                if(me[k].lx<=tmpx&&me[k].rx>=tmpx&&me[w].lx<=tmpx&&me[w].rx>=tmpx)

                                {

                                    li[tmpk]=tmpw;

                                    num[tmpw]+=num[tmpk];

                                }

                            }

                            else if(me[k].ok)

                            {

                                if(me[k].lx<=me[w].lx&&me[k].rx>=me[w].rx)

                                {

                                    li[tmpk]=tmpw;

                                    num[tmpw]+=num[tmpk];

                                }

                            }

                            else if(me[w].ok)

                            {

                                if(me[w].lx<=me[k].lx&&me[w].lx>=me[k].rx)

                                {

                                    li[tmpk]=tmpw;

                                    num[tmpw]+=num[tmpk];

                                }

                            }

                            else if(me[w].lx==me[k].lx)

                            {

                                li[tmpk]=tmpw;

                                num[tmpw]+=num[tmpk];

                            }

                        }

                    }

                    k++;

                }

                else if(typ=='Q')

                {

                    scanf("%d",&tmp);

                    tmp=findme(tmp);

                    printf("%d\n",num[tmp]);

                }

                getchar();

            }

            if(i!=t)//输出大坑

                printf("\n");

        }

    }

    return 0;

}

 

你可能感兴趣的:(HDU)