zoukankan      html  css  js  c++  java
  • 一条直线上N个线段所覆盖的总长度

    原文:http://blog.csdn.net/bxyill/article/details/8962832

    问题描述:

    现有一直线,从原点到无穷大。

    这条直线上有N个线段。线段可能相交。

    问,N个线段总共覆盖了多长?(重复覆盖的地区只计算一次)

    ================================================

    解题思路:

    可以将每个线段拆分成“单位1”

    遍历所有线段,使用一个数组记录每个线段所走过的“单位1”

    最后统计数组中被走过的中“单位1”的个数,即是所有线段覆盖的总长度了。

    这里有个问题?数组的大小如何确定?

    数组的大小应该是所有线段中最大的端点坐标。

     ===============================================

    顺便想到一个问题。

    给出若干个线段。求一共有几个“连通域”。就是将能合并的线段 合并成一个线段。

    最后能合并出几个来?

    利用上面的思想。非常简单。

    只需遍历单位数组的时候做个开始和结尾的记录就行了。

    程序实现如下。

    ===============================================

    [cpp] view plaincopy
     
    1. //此题要求  
    2. //求出一条直线上所有线段所覆盖的全程长度是多少。  
    3. //重叠的地方只计算一次。  
    4. //================================  
    5. //本算法的思想是,将每个线段进行像素化,  
    6. //添加到一个单位数组c[N]中  
    7. //遍历c数组判断哪些单位被覆盖到了,  
    8. //在count计数一下就知道一共覆盖了多少路程。  
    9. //真是巧妙啊。  
    10. //==============================  
    11. #include <iostream>  
    12. using namespace std;  
    13. const int N = 10000;  
    14. //线段结构体  
    15. struct Segment  
    16. {  
    17.     int start;  
    18.     int end;  
    19. };  
    20. //  
    21. int coverage(Segment *segments, int n)  
    22. {  
    23.     bool c[N]={false};//每个“单位1”是否被覆盖到  
    24.   
    25.     int start=0;  
    26.     int end = 0;  
    27.     //遍历n个线段  
    28.     for(int i = 0; i < n; i++)  
    29.     {  
    30.         for(int j = segments[i].start; j < segments[i].end; j++)  
    31.         {  
    32.             c[j] = true;  
    33.         }  
    34.         //寻找最右端  
    35.         if(segments[i].end > end)  
    36.         {  
    37.             end = segments[i].end;  
    38.         }  
    39.         //寻找最左端  
    40.         if(segments[i].start < start)  
    41.         {  
    42.             start = segments[i].start;  
    43.         }  
    44.     }  
    45.     //从最左端开始到最右端。遍历单位数组C  
    46.     int count = 0;  
    47.     for(int i= start; i < end; i++)  
    48.     {  
    49.         if(c[i])  
    50.         {  
    51.             int s=i;  
    52.             while(c[i])  
    53.             {  
    54.                 count++;  
    55.                 i++;  
    56.             }  
    57.             int e=i;  
    58.             cout << "["<<s<<","<<e<<"]"<<endl;  
    59.         }  
    60.     }  
    61.     return count;  
    62. };  
    63.   
    64. int main()  
    65. {  
    66.     Segment s1;  
    67.     s1.start = 1;  
    68.     s1.end = 3;  
    69.   
    70.     Segment s2;  
    71.     s2.start = 2;  
    72.     s2.end = 6;  
    73.   
    74.     Segment s3;  
    75.     s3.start = 11;  
    76.     s3.end = 12;  
    77.   
    78.     Segment s4;  
    79.     s4.start = 10;  
    80.     s4.end = 13;  
    81.     Segment ss[] = {s1,s2,s3,s4};  
    82.     cout << "归并后"<<endl;  
    83.     cout <<"被覆盖总长度:" <<coverage(ss, sizeof(ss)/sizeof(ss[0]))<<endl;  
    84. }  

    输出结果如下:

    归并后
    [1,6]
    [10,13]

    被覆盖总长度
    8

    请按任意键继续. . .

  • 相关阅读:
    php流程控制
    php运算符
    php数据类型
    php基础
    谈谈2019年
    聊聊这三年
    第二次作业(源代码)
    个人介绍
    22.python匿名函数详解
    11.python内置模块之json模块
  • 原文地址:https://www.cnblogs.com/zhizhan/p/4868114.html
Copyright © 2011-2022 走看看