提高效率“灯塔”

时间:2013-12-17 05:36:24

标签: c algorithm data-structures

问题描述:

海里有很多灯塔。海的范围是[1, 10^7] × [1, 10^7]

每个灯塔都可以照亮西南和东北地区。光的力量应该覆盖任何距离。

enter image description here

如果灯塔A和B在那里照明区域,说它们可以相互照亮。

输入有n + 1行: 第一行是灯塔的数量。 第n行 行的第二行是灯塔的水平和垂直坐标。

输出有一行: 这对灯箱可以相互照亮。

例如:

intput:

3
2 2
4 3
5 1

输出:

1

请注意:

灯塔的坐标为int。所有灯塔的水平和垂直坐标都不同。

1 ≤ x, y ≤ 10^7

我的代码效率非常低。请帮我修改我的代码。非常感谢你!

这是我的代码。

    #include<stdlib.h>
    int main()
    {
        int n,i,j,s;
        int *x,*y;
        scanf("%d",&n);
        x=(int *)malloc(n*sizeof(int));
        y=(int *)malloc(n*sizeof(int));
        for(i=0;i<n;i++)
        {
           scanf("%d %d",&x[i],&y[i]);
        }
        s=0;
        for(i=0;i<n-1;i++)
        for(j=i+1;j<n;j++)
        {
        if((x[i]>x[j]&&y[i]>y[j])||(x[i]<x[j]&&y[i]<y[j]))
            s++;
        }
        printf("%d\n",s);
        free(x);
        free(y);
        return 0;
        }

1 个答案:

答案 0 :(得分:1)

我没有足够的声誉直接发表评论,所以我会详细说明并在此留下答案。

你的算法使用嵌套循环进行成对计算并且具有O(n 2 )时间复杂度,这就是为什么你的算法对于大输入来说很慢的原因(这里大的并不意味着坐标值,但是灯塔的数量)。首先让我们看看我们可以做些什么来优化,输入样本:

3
1 1(P a
2 2(P b
3 3(P c

使用您的算法,执行逻辑将是:

  1. 计数= 0
  2. P a 和P b 是一对?没错,算上++
  3. P a 和P c 是一对?没错,算上++
  4. P b 和P c 是一对?没错,算上++
  5. 输出计数
  6. 实际上有多余的计算可以消除:

    确定现有的灯塔是否可以照亮新增加的灯塔。

    请注意,P a 的NE区域实际上包含P b 的NE区域,因此如果新的灯塔属于P b 的NE区域,隐含地意味着它被P a 以及P b 所照亮。因此,如果我们在海中有P a 和P b 并添加P c ,我们实际上不需要用P <计算两次sub> a 和P b 分开。

    假设我们有以下记录记录灯塔的照明交叉区域:
    一个。计数= 0; R = {}
    湾添加P a ,R = {[( - ∞,-∞),(1,1)] - > [P a ],[(1,1) ,(∞,∞)] - &gt; [P a ]}([(-∞,-∞),(1,1)]和[(1,1),(∞,∞) )]定义两个带有对角点的矩形区域)
    c。添加P b ,P b 在[(1,1),(∞,∞)]中(这意味着[P a ]可以照亮P b ),找到可以被P b 照亮的[P a ]中的所有灯塔,即P a < / sub>,count + = 1,R = {[( - ∞,-∞),(1,1)] - &gt; [P a ,P b ] ,[( - ∞,1),(1,2)] - &GT; [P <子> b'/子>],[(1,-∞),(2,1)] - &GT; [P <子> b'/子>],[(1,1),(2,2)] - &GT; [P <子>一,P <子> b'/子>],[(1- ,2),(2,∞)] - &GT; [P <子> b'/子>],[(2,1),(∞,2)] - &GT; [P <子> b'/子>],[(2,2),(∞,∞)] - &GT; [P <子>一,P <子> b'/子>]}
    d。添加P c ,P c 在[(2,2),(∞,∞)]中,找到[P a ,P b ]可以被[P a ,P b ]照亮,即P a , P b ,count + = 2,更新R(太长了所以我在这里省略它)

    enter image description here

    您可能想要表示的一个数据结构R是一个分段树1。这里适用的分段树是二维的。我建议您查看现有的帖子How to code 2D segment tree?,然后尝试实现自己的帖子。

    1 http://en.wikipedia.org/wiki/Segment_tree