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;
}
时间: 2024-10-22 23:30:22

HDU 1558的相关文章

HDU 1558 Segment set (并查集+线段非规范相交)

题目链接 题意 : 如果两个线段相交就属于同一集合,查询某条线段所属集合有多少线段,输出. 思路 : 先判断与其他线段是否相交,然后合并. 1 //1558 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <cmath> 6 #define eps 1e-8 7 #define zero(x) (((x) > 0 ? (x) : (-x)) < e

hdu 1558 (线段相交+并查集) Segment set

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1558 题意是在坐标系中,当输入P(注意是大写,我当开始就wa成了小写)的时候输入一条线段的起点坐标和终点坐标,当输入Q的时候输入n,然后输出与第n条线段相交的线段有多少条 首先判断线段是否相交,在算法导论p577上有介绍 线段A(x1,y1)-B(x2,y2),所在直线L1方程为F1(x,y)=0;线段C(x3,y3)-D(x4,y4),所在直线L2方程为F2(x,y)=0; 如何判断两条线段有交点:(

hdu 1558 线段相交+并查集路径压缩

Segment set Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3457    Accepted Submission(s): 1290 Problem Description A segment and all segments which are connected with it compose a segment set.

hdu 1558 Segment set

#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <string> #include <ma

hdu 1558 Segment set【基础带权并查集+计算几何】

Segment set Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3599    Accepted Submission(s): 1346 Problem Description A segment and all segments which are connected with it compose a segment set

hdu 1558(计算几何+并查集)

Segment set Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4479    Accepted Submission(s): 1672 Problem Description A segment and all segments which are connected with it compose a segment set.

HDU 1558 Segment set(并查集之三)

问题描述: Problem Description A segment and all segments which are connected with it compose a segment set. The size of a segment set is the number of segments in it. The problem is to find the size of some segment set. Input In the first line there is a

hdu 1558 Segment set(并查集+判断线段是否相交)

代码: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int father[1005]; int son_cnt[1005]; char s[5]; //int cnt; struct point { double x,y; }; point a[1005],b[1005]; int find_father(int x) { int r=x; while(fathe

hdu 1558 Segment set (并查集)

Segment set Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3907    Accepted Submission(s): 1471 Problem Description A segment and all segments which are connected with it compose a segment set