zoukankan      html  css  js  c++  java
  • 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;

    如何判断两条线段有交点:(A,B在直线L2两侧) AND (C,D在直线L1两侧)。

    用数学表达式来表示可以这样来表示:F2(x1,y1)*F2(x2,y2) >= 0 AND F1(x3,y3)*F1(x4,y4)>= 0; 等于0表示恰好在直线上

    然后就是基础的并查集判断是否在一个集合以及集合内的线段的个数

     1 #include<cstdio>
     2 using namespace std;
     3 int father[1001],num[1001];
     4 void give()
     5 {
     6     for (int i=1;i<=1000;i++)
     7     {
     8         father[i]=i;
     9         num[i]=1;
    10     }
    11 }
    12 int _find(int x)
    13 {
    14     if (father[x]==x) return father[x];
    15     father[x]=_find(father[x]);
    16     return father[x];
    17 }
    18 double x1[1001],x2[1001],y1[1001],y2[1001];
    19 double a[1001],b[1001];
    20 int main()
    21 {
    22     int t,n,sx,sy,k,i,q;
    23     char op;
    24     scanf("%d",&t);
    25         while (t--)
    26         {
    27             scanf("%d",&n);
    28             give();k=1;
    29             while (n--)
    30             {
    31                 scanf(" %c",&op);
    32                 if (op=='P')
    33                 {
    34                     scanf("%lf %lf %lf %lf",&x1[k],&y1[k],&x2[k],&y2[k]);
    35                     a[k]=(y2[k]-y1[k])/(x2[k]-x1[k]);
    36                     b[k]=(x2[k]*y1[k]-x1[k]*y2[k])/(x2[k]-x1[k]);
    37                     for (i=1;i<k;i++)
    38                     {
    39                         int t1=0,t2=0;
    40                         if (!((a[k]*x1[i]-y1[i]+b[k])*(a[k]*x2[i]-y2[i]+b[k])>0))
    41                             t1=1;
    42                         if (!((a[i]*x1[k]-y1[k]+b[i])*(a[i]*x2[k]-y2[k]+b[i])>0))
    43                             t2=1;
    44                         if (t1==1&&t2==1)
    45                         {
    46                             sx=_find(k);
    47                             sy=_find(i);
    48                             if (sx!=sy){
    49                             father[sx]=sy;
    50                             num[sy]+=num[sx];
    51                             }
    52                         }
    53                     }
    54                     k++;
    55                 }
    56                 else
    57                 {
    58                     scanf("%d",&q);
    59                     printf("%d
    ",num[_find(q)]);
    60                 }
    61             }
    62             if (t) printf("
    ");
    63         }
    64     return 0;
    65 }
  • 相关阅读:
    ruby html解析器
    国外cdn
    ruby爬虫utf8编码相关
    Ruby 1.9 regex (named capture group)正则名组
    ruby爬虫综述
    ruby新加实例方法写法
    机房
    Net::HTTP Cheat Sheet
    ror一键安装包forwin
    病毒6655.la
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/4827233.html
Copyright © 2011-2022 走看看