Algorithms – Programming Assignment 4: Divide-and-Conquer (Solution)

$ 24.99

Description

Introduction
In this programming assignment, you will be practicing implementing divide-and-conquer solutions.
Learning Outcomes
Upon completing this programming assignment you will be able to:
1. Apply the divide-and-conquer technique to solve various computational problems efficiently. This will usually require you to design an algorithm that solves a problem by splitting it into several disjoint subproblems, solving them recursively, and then combining their results to get an answer for the initial problem.
2. Design and implement efficient algorithms for the following computational problems:
(a) searching a sorted data for a key;
(b) finding a majority element in a data;
(c) improving the quick sort algorithm;
(d) checking how close a data is to being sorted;
(e) organizing a lottery;
(f) finding the closest pair of points.
Passing Criteria: 3 out of 6
Passing this programming assignment requires passing at least 3 out of 6 programming challenges from this assignment. In turn, passing a programming challenge requires implementing a solution that passes all the tests for this problem in the grader and does so under the time and memory limits specified in the problem statement.
Contents
1 Binary Search 3
2 Majority Element 4
3 Improving Quick Sort 6
4 Number of Inversions 7
5 Organizing a Lottery 8
6 Closest Points 10

1 Binary Search
Problem Introduction
In this problem, you will implement the binary search algorithm that allows searching very efficiently (even huge) lists, provided that the list is sorted.
Problem Description
Task. The goal in this code problem is to implement the binary search algorithm.
Input Format. The first line of the input contains an integer n and a sequence a0 < a1 < … < an−1 of n pairwise distinct positive integers in increasing order. The next line contains an integer k and k positive integers b0,b1,…,bk−1.
Constraints. 1 ≤ n,k ≤ 104; 1 ≤ ai ≤ 109 for all 0 ≤ i < n; 1 ≤ bj ≤ 109 for all 0 ≤ j < k;
Output Format. For all i from 0 to k − 1, output an index 0 ≤ j ≤ n − 1 such that aj = bi or −1 if there is no such index.
Sample 1.
Input:
51581213
58123111
Output:
20-10-1
In this sample, we are given an increasing sequence a0 = 1, a1 = 5, a2 = 8, a3 = 12, a4 = 13 of length five and five keys to search: 8,1,23,1,11. We see that a2 = 8 and a0 = 1, but the keys 23 and 11 do not appear in the sequence a. For this reason, we output a sequence 2,0,−1,0,−1.
Need Help?
Ask a question or see the questions asked by other learners at this forum thread.
2 Majority Element
Problem Introduction
Majority rule is a decision rule that selects the alternative which has a majority, that is, more than half the votes.
MajorityElement(a1,a2,…,an):
for i from 1 to n:
currentElement ← ai count ← 0 for j from 1 to n:
if aj = currentElement:
count ← count + 1
if count > n/2:
return ai
return“nomajorityelement”
Given a sequence of elements a1,a2,…,an, you would like to check whether it contains an element that appears more than n/2 times. A naive way to do this is the following.
The running time of this algorithm is quadratic. Your goal is to use the divide-and-conquer technique to design an O(nlogn) algorithm.
Problem Description
Task. The goal in this code problem is to check whether an input sequence contains a majority element.
Input Format. The first line contains an integer n, the next one contains a sequence of n non-negative integers a0,a1,…,an−1.
Constraints. 1 ≤ n ≤ 105; 0 ≤ ai ≤ 109 for all 0 ≤ i < n.
Output Format. Output 1 if the sequence contains an element that appears strictly more than n/2 times, and 0 otherwise.
Sample 1.
Input:
5
23922
Output:
1
2 is the majority element.
Sample 2.
Input:
4
1234
Output:
0
There is no majority element in this sequence.
Sample 3.
Input:
4
1231
Output:
0
This sequence also does not have a majority element (note that the element 1 appears twice and hence is not a majority element).
What To Do
As you might have already guessed, this problem can be solved by the divide-and-conquer algorithm in time O(nlogn). Indeed, if a sequence of length n contains a majority element, then the same element is also a majority element for one of its halves. Thus, to solve this problem you first split a given sequence into halves and make two recursive calls. Do you see how to combine the results of two recursive calls?
It is interesting to note that this problem can also be solved in O(n) time by a more advanced (non-divide and conquer) algorithm that just scans the given sequence twice.
Need Help?
Ask a question or see the questions asked by other learners at this forum thread.
3 Improving Quick Sort
Problem Introduction
The goal in this problem is to redesign a given implementation of the randomized quick sort algorithm so that it works fast even on sequences containing many equal elements.
Problem Description
Task. To force the given implementation of the quick sort algorithm to efficiently process sequences with few unique elements, your goal is replace a 2-way partition with a 3-way partition. That is, your new partition procedure should partition the array into three parts: < x part, = x part, and > x part.
Input Format. The first line of the input contains an integer n. The next line contains a sequence of n integers a0,a1,…,an−1.
Constraints. 1 ≤ n ≤ 105; 1 ≤ ai ≤ 109 for all 0 ≤ i < n.
Output Format. Output this sequence sorted in non-decreasing order.
Sample 1.
Input:
5
23922
Output:
22239
Starter Files
In the starter files, you are given an implementation of the randomized quick sort algorithm using a 2-way partition procedure. This procedure partitions the given array into two parts with respect to a pivot x: ≤ x part and > x part. As discussed in the video lectures, such an implementation has Θ(n2) running time on sequences containing a single unique element. Indeed, the partition procedure in this case splits the array into two parts, one of which is empty and the other one contains n − 1 elements. It spends cn time on this. The overall running time is then
cn + c(n − 1) + c(n − 2) + … = Θ(n2).
What To Do
Implement a 3-way partition procedure and then replace a call to the 2-way partition procedure by a call to the 3-way partition procedure.
Need Help?
Ask a question or see the questions asked by other learners at this forum thread.
4 Number of Inversions
Problem Introduction
An inversion of a sequence a0,a1,…,an−1 is a pair of indices 0 ≤ i < j < n such that ai > aj. The number of inversions of a sequence in some sense measures how close the sequence is to being sorted. For example, a sorted (in non-descending order) sequence contains no inversions at all, while in a sequence sorted in descending order any two elements constitute an inversion (for a total of n(n − 1)/2 inversions).
Problem Description
Task. The goal in this problem is to count the number of inversions of a given sequence.
Input Format. The first line contains an integer n, the next one contains a sequence of integers
a0,a1,…,an−1.
Constraints. 1 ≤ n ≤ 105, 1 ≤ ai ≤ 109 for all 0 ≤ i < n.
Output Format. Output the number of inversions in the sequence.
Sample 1.
Input:
5
23929
Output:
2
The two inversions here are (1,3) (a1 = 3 > 2 = a3) and (2,3) (a2 = 9 > 2 = a3).
What To Do
This problem can be solved by modifying the merge sort algorithm. For this, we change both the Merge and MergeSort procedures as follows:
∙ Merge(B, C) returns the resulting sorted array and the number of pairs (b,c) such that b ∈ B, c ∈ C, and b > c;
∙ MergeSort(A) returns a sorted array A and the number of inversions in A.
Need Help?
Ask a question or see the questions asked by other learners at this forum thread.
5 Organizing a Lottery
Problem Introduction
You are organizing an online lottery. To participate, a person bets on a single integer. You then draw several ranges of consecutive integers at random. A participant’s payoff then is proportional to the number of ranges that contain the participant’s number minus the number of ranges that does not contain it. You need an efficient algorithm for computing the payoffs for all participants. A naive way to do this is to simply scan, for all participants, the list of all ranges. However, you lottery is very popular: you have thousands of participants and thousands of ranges. For this reason, you cannot afford a slow naive algorithm.
Problem Description
Task. You are given a set of points on a line and a set of segments on a line. The goal is to compute, for each point, the number of segments that contain this point.
Input Format. The first line contains two non-negative integers s and p defining the number of segments and the number of points on a line, respectively. The next s lines contain two integers ai,bi defining the i-th segment [ai,bi]. The next line contains p integers defining points x1,x2,…,xp.
Constraints. 1 ≤ s,p ≤ 50000; −108 ≤ ai ≤ bi ≤ 108 for all 0 ≤ i < s; −108 ≤ xj ≤ 108 for all 0 ≤ j < p.
Output Format. Output p non-negative integers k0,k1,…,kp−1 where ki is the number of segments which contain xi. More formally, ki = |{j: aj ≤ xi ≤ bj}|.
Sample 1.
Input:
23
05
710
1611
Output:
100
Here, we have two segments and three points. The first point lies only in the first segment while the remaining two points are outside of all the given segments.
Sample 2.
Input:
13
-1010
-1001000
Output:
001
Sample 3.
Input:
32
05
-32
710
16
Output:
20
Need Help?
Ask a question or see the questions asked by other learners at this forum thread.
6 Closest Points
Problem Introduction
In this problem, your goal is to find the closest pair of points among the given n points. This is a basic primitive in computational geometry having applications in, for example, graphics, computer vision, traffic-control systems.
Problem Description
Task. Given n points on a plane, find the smallest distance between a pair of two (different) points. Recall

that the distance between points (x1,y1) and (x2,y2) is equal to √︀(x1 − x2)2 + (y1 − y2)2.
Input Format. The first line contains the number n of points. Each of the following n lines defines a point
(xi,yi).
Constraints. 2 ≤ n ≤ 105; −109 ≤ xi,yi ≤ 109 are integers.
Output Format. Output the minimum distance. The absolute value of the difference between the answer of your program and the optimal value should be at most 10−3. To ensure this, output your answer with at least four digits after the decimal point (otherwise your answer, while being computed correctly, can turn out to be wrong because of rounding issues).
Sample 1.
Input:
2
00
34
Output:
5.0
There are only two points here. The distance between them is 5.
Sample 2.
Input:
4
77
1100
48
77
Output:
0.0
There are two coinciding points among the four given points. Thus, the minimum distance is zero.
Sample 3.
Input:
11
44
-2-2
-3-4
-13 23
-40
11
-1-1
3-1
-42
-24
Output:
1.414213

The smallest distance is 2. There are two pairs of points at this distance: (−1,−1) and (−2,−2); (−2,4) and (−1,3).

What To Do
This computational geometry problem has many applications in computer graphics and vision. A naive algorithm with quadratic running time iterates through all pairs of points to find the closest pair. Your goal is to design an O(nlogn) time divide and conquer algorithm.
To solve this problem in time O(nlogn), let’s first split the given n points by an appropriately chosen vertical line into two halves S1 and S2 of size (assume for simplicity that all x-coordinates of the input points are different). By making two recursive calls for the sets S1 and S2, we find the minimum distances d1 and d2 in these subsets. Let d = min{d1,d2}.
d2
It remains to check whether there exist points p1 ∈ S1 and p2 ∈ S2 such that the distance between them is smaller than d. We cannot afford to check all possible such pairs since there are of them. To check this faster, we first discard all points from S1 and S2 whose x-distance to the middle line is greater than d. That is, we focus on the following strip:

Stop and think: Why can we narrow the search to this strip? Now, let’s sort the points of the strip by their y-coordinates and denote the resulting sorted list by P = [p1,…,pk]. It turns out that if |i − j| > 7, then the distance between points pi and pj is greater than d for sure. This follows from the Exercise Break below.
Exercise break: Partition the strip into d × d squares as shown below and show that each such square contains at most four input points.

This results in the following algorithm. We first sort the given n points by their x-coordinates and then split the resulting sorted list into two halves S1 and S2 of size . By making a recursive call for each of the sets S1 and S2, we find the minimum distances d1 and d2 in them. Let d = min{d1,d2}. However, we are not done yet as we also need to find the minimum distance between points from different sets (i.e, a point from S1 and a point from S2) and check whether it is smaller than d. To perform such a check, we filter the initial point set and keep only those points whose x-distance to the middle line does not exceed d. Afterwards, we sort the set of points in the resulting strip by their y-coordinates and scan the resulting list of points. For each point, we compute its distance to the seven subsequent points in this list and compute d′, the minimum distance that we encountered during this scan. Afterwards, we return min{d,d′}. The running time of the algorithm satisfies the recurrence relation
.
The O(nlogn) term comes from sorting the points in the strip by their y-coordinates at every iteration.
Exercise break: Prove that T(n) = O(nlog2 n) by analyzing the recursion tree of the algorithm.
Exercise break: Show how to bring the running time down to O(nlogn) by avoiding sorting at each recursive call.
Need Help?
Ask a question or see the questions asked by other learners at this forum thread.

Reviews

There are no reviews yet.

Be the first to review “Algorithms – Programming Assignment 4: Divide-and-Conquer (Solution)”

Your email address will not be published. Required fields are marked *