Codility Lesson 4 NumberOfDiscIntersections 解答

Thinking:

1. Look every circle as a range, that will help us think in a simpler way. So the first step is translate circles into ranges(from "center&radius" to range):

A[0]=1    >>    [-1,1]

A[1]=5    >>    [-4,6]

A[2]=2    >>    [0,4]

A[3]=1    >>    [2,4]

A[4]=4    >>    [0,8]

A[5]=0    >>    [5,5]

2. Now, let's draw these ranges in a horizontal axis, so that every intersection is clear.

3. After understanding this theory, I believe you've fully understand the question. The next step is to find a way to calculate the intersections distinctively.

4. There is an idea that we can count the intersections along the index of array A[N], but the problem is recounting. If the intersection of two ranges has been counted in the previous index, and they still have intersection in the following index(s), it's easy to get a wrong result.

5. So, we need a variable to record the total ranges existing according to the current index. And 2 arrays to record when the starts and ends of the ranges, so that we know how many ranges is new when we move to the next index, which is really need to be counted the intersections with each other(See line 22). After these new ranges count their own intersections, they also need to count intersections with the existing ranges(See line 20).

6. In general, the most important thought has been shown. While there are still some traps should be valued, which will affect on the score. 

  • Take care the (A[i] + i) exceeds the value of MAX int<span style="font-family: Arial, Helvetica, sans-serif;">, which will become minus int.
  • Return -1, when the result exceeds 10,000,000.

7. Hope it's not difficult to understand, if not, feel free to leave a message, we can talk about your question.


Solution in Java:

class Solution {
    public int solution(int[] A) {
        // write your code in Java SE 8
        int l = A.length;
        int[] arrayIn = new int[l];
        int[] arrayOut = new int[l];
        int inNumContext = 0;
        int result = 0;
        
        for(int i = 0; i < l; i ++) {
            int in = (i - A[i]) < 0 ? 0 : (i - A[i]);
            // take care the (A[i] + i) exceeds the value of MAX int 
            // which will become minus int
            int out = (A[i] + i > l - 1 || A[i] + i < 0) ? (l - 1) : (A[i] + i);
            arrayIn[in] ++;
            arrayOut[out] ++;
        }
        
        
        for(int i = 0; i < l; i ++) {
            if(arrayIn[i] != 0) {
                // previous circles times new coming circles
                result += inNumContext * arrayIn[i];
                // new coming circles group with each other
                result += arrayIn[i] * (arrayIn[i] - 1) / 2;
                
                if (result > 10000000) {
                    return -1;
                }
                
                // add coming circles to inNumContext
                inNumContext += arrayIn[i];
            }
            // minus leaving circles from inNumContext
            inNumContext -= arrayOut[i];
        } 
        
        return result;
    }
}



Task description:

Given an array A of N integers, we draw N discs in a 2D plane such that the I-th disc is centered on (0,I) and has a radius of A[I]. We say that the J-th disc and K-th disc intersect if J ≠ K and J-th and K-th discs have at least one common point.

Write a function:

class Solution { public int solution(int[] A); }

that, given an array A describing N discs as explained above, returns the number of pairs of intersecting discs. For example, given N=6 and:

A[0] = 1  A[1] = 5  A[2] = 2
A[3] = 1  A[4] = 4  A[5] = 0

intersecting discs appear in eleven pairs of elements:

  • 0 and 1,
  • 0 and 2,
  • 0 and 4,
  • 1 and 2,
  • 1 and 3,
  • 1 and 4,
  • 1 and 5,
  • 2 and 3,
  • 2 and 4,
  • 3 and 4,
  • 4 and 5.

so the function should return 11.

The function should return −1 if the number of intersecting pairs exceeds 10,000,000.

Assume that:

  • N is an integer within the range [0..100,000];
  • each element of array A is an integer within the range [0..2147483647].

Complexity:

  • expected worst-case time complexity is O(N*log(N));
  • expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).

Elements of input arrays can be modified.

Copyright 2009–2015 by Codility Limited. All Rights Reserved. Unauthorized copying, publication or disclosure prohibited.


Reference: http://www.rationalplanet.com/php-related/numberofdiscintersections-beta2010-demo-task-at-codility-com.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在课程中添加一个作业是一个很重要的步骤。作业可以帮助学生巩固他们所学到的知识,并帮助教师评估学生的学习进度和掌握程度。 首先,一个好的作业应该与课堂教学内容相结合。教师可以设计作业来帮助学生将课堂上学到的概念应用到实际问题中,或者进一步发掘和探索学生的思考能力。作业应该涵盖课程中的关键点和重要概念,以帮助学生加深对这些知识的理解。 其次,作业应该有明确的目标和要求。教师应该清楚地告诉学生他们需要完成什么,并给出明确的评估标准。这样一来,学生可以知道他们需要达到什么样的水平,并能有针对性地完成任务。 此外,作业应该适当地安排时间。教师需要考虑学生在完成作业时所需的时间,并在布置作业时给出合理的截止日期。这样一来,学生可以有足够的时间来完成作业,并且可以避免时间紧张导致的学习压力。 最后,作业的评估和反馈也是很重要的。教师可以通过评估学生的作业来了解学生的掌握程度,并根据作业的质量给出相应的反馈和建议。这样一来,学生可以知道他们的学习状况,并可以及时地调整学习策略。 总之,将作业添加到课程中是一个促进学生学习和教学效果的重要步骤。一个好的作业可以帮助学生加深对知识的理解,提高他们的学习效果。同时,教师通过评估和反馈也可以更好地了解学生的学习情况,并为他们提供相应的指导和支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值