zoukankan      html  css  js  c++  java
  • Segment set

    题目大意:

      在一个平面上,给定N根线段,若某条线段与另一条线段相交,则将它们归于同个集合,给定k,问第k条线段所在的集合中线段的数量。

    题目分析:

      问题主要考察计算几何和并查集。

      首先我们要判断两条线段是否能相交:线段P1P2与线段Q1Q2相交时,向量P1P2是夹在向量P1Q1和向量P1Q2中间,并且向量Q1Q2夹在向量Q1P1和Q1P2中间。这个可以用向量的叉乘来判断,如要判断向量P1P2是夹在向量P1Q1和向量P1Q2中间,只需判断 P1P2×P1Q1 * P1P2×P1Q2 < 0即可。但向量P1P2可能与Q1Q2共线,用刚才的叉乘的方法判别就得是:P1P2×P1Q1 * P1P2×P1Q2 = 0,并且线段P1P2和Q1Q2有部分重叠。

      然后就可以用并查集的套路进行解题了。

    代码:

     1 #include<iostream>
     2 using namespace std;
     3 static int set[1005];
     4 static int num[1005];
     5 struct point{
     6     double x, y;
     7 };
     8 struct edge{
     9     point a, b;
    10 }e[1005];
    11 double cross(point a,point b,point c){//三点的叉乘  
    12     return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);  
    13 } 
    14 bool OnSegment(point a,point b,point c){//判断是否有重叠   
    15     return c.x>=min(a.x,b.x)&&c.x<=max(a.x,b.x)&&c.y>=min(a.y,b.y)&&c.y<=max(a.y,b.y);  
    16 }
    17 
    18 bool intersect(point a,point b,point c,point d) //判断是否相交  
    19 {  
    20     double d1,d2,d3,d4;  
    21     d1 = cross(c, d, a);  
    22     d2 = cross(c, d, b);  
    23     d3 = cross(a, b, c);  
    24     d4 = cross(a, b, d);  
    25     if(d1 * d2 < 0 && d3 * d4 < 0)  return 1;  
    26     else if(d1 == 0 && OnSegment(c,d,a)) return 1;  
    27     else if(d2 == 0 && OnSegment(c,d,b)) return 1;  
    28     else if(d3 == 0 && OnSegment(a,b,c)) return 1;  
    29     else if(d4 == 0 && OnSegment(a,b,d)) return 1;  
    30     return 0;  
    31 }
    32 
    33 int find(int x){
    34     int temp = x;
    35     while( set[temp] != temp ){
    36         temp = set[temp];
    37     }
    38     int root = temp;
    39     temp = x;
    40     while(set[temp] != root){
    41         int t = temp;
    42         temp = set[temp];
    43         set[t] = root;
    44     }
    45     return root;
    46 }
    47 
    48 void merge(int x, int y){
    49     int fx = find(x);
    50     int fy = find(y);
    51     if(fx < fy){
    52         set[fy] = fx;
    53         num[fx] += num[fy];
    54     }
    55     else if(fx > fy){
    56         set[fx] = fy;
    57         num[fy] += num[fx];
    58     }
    59 }    
    60 int main(int argc, char const *argv[]){    
    61     int t, n;
    62     cin >> t;
    63     while(t--){
    64         cin >> n;
    65         
    66         int k = 0;
    67         for(int i = 0; i <= n; i++){
    68             set[i] = i;
    69             num[i] = 1;
    70         }
    71 
    72         while(n--){
    73             string s;
    74             cin >> s;
    75             if(s == "P"){
    76                 k++;
    77                 cin >> e[k].a.x >> e[k].a.y >> e[k].b.x >> e[k].b.y;
    78                 for(int j = 1; j <= k; j++){
    79                     if(find(k) != find(j) && intersect(e[k].a, e[k].b, e[j].a, e[j].b)) {
    80                      merge(k,j); 
    81                      //break; 
    82                     }  
    83                 }
    84             }
    85             else if(s == "Q"){
    86                 int m;
    87                 cin >> m;
    88                 cout << num[find(m)] << endl;
    89             }
    90             
    91         }
    92         if(t) cout << endl;
    93     }
    94     
    95     return 0;
    96 }
  • 相关阅读:
    You are not late! You are not early!
    在同一个服务器(同一个IP)为不同域名绑定的免费SSL证书
    Vue.js Is Good, but Is It Better Than Angular or React?
    It was not possible to find any compatible framework version
    VS增加插件 Supercharger破解教程
    Git使用ssh key
    Disconnected: No supported authentication methods available (server sent: publickey)
    VS 2013打开.edmx文件时报类型转换异常
    asp.net MVC4 框架揭秘 读书笔记系列3
    asp.net MVC4 框架揭秘 读书笔记系列2
  • 原文地址:https://www.cnblogs.com/Vincent-Bryan/p/5557910.html
Copyright © 2011-2022 走看看