1 Divide and ConquerA group of n Ghostbusters is battling n ghosts. Each Ghostbuster is armed with a proton pack, which shoots a stream at a ghost, eradicating it. A stream goes in a straight line and terminates when it hits the ghost. The Ghostbusters decide upon the following strategy. They will pair off with the ghosts, forming n Ghostbuster-ghost pairs, and then simultaneously each Ghostbuster will shoot a stream at his chosen ghost. As we all know, it is very dangerous to let streams cross, and so the Ghostbusters must choose pairings for which no streams will cross. Assume that the position of each Ghostbuster and each ghost is a fixed point in the plane and that no three positions are collinear.i Argue that there exists a line passing through one Ghostbuster and one ghost such the number of Ghostbusters on one side of the line equals the number of ghosts on the same side. Describe how to find such a line in O(n log n) time.ii Give an O(n2 log n)-time algorithm to pair Ghostbusters with ghosts in such a way that no streams cross.Answer:i -ii: We assume that all the points in the plane are not in same X or Y axis using mark to stand for ghostbuster or ghosts(mark 0 stand for ghostbuster and mark 1 stand for ghosts).(This can not affect the problem because when we get the same X or Y , we can add or minus a very little value to let all points’ X or Y are not same). First we get the deepest point (in other word, the minimum Y value). Also we compute the other points with this point ‘s angle in X axis and sort these other points with this angle. Then we iterate in this order, and get another mark which is different from the deepest point's mark also we line this twopoint ,and compute the bottom mark 0 's number and mark 1's number, they are the same , then we find the pair which is the deepest point and the iterate point. So we use this line to divide all points into two parts and recursive do the same above operation until the points' number is only 2 then we only get the line to connect this two points.Algorithm:Get_Pair(points[1-2N])if N>1initial a array points[1-2N] stand for the points of ghostbusters and ghostsfind the deepest point min_Point in the array pointsinitial the pair_Point and the index with 0get the other 2N-1 points with this min_Point 's angle in X axis and sort these anglesinitial num1 with 0 stand for the number of the other 2N-1 points which's mark is same with min_Pointinitial num2 with 0 stand for the number of the other 2N-1 points which's mark is not same with min_Pointfor i=1 to 2N-1if min_Point's mark is same with points[i]'s marknum1++elsenum2++endifif num1+1==num2get this point pair_Pointindex=ibreak;endifendforprint this pair (min_Point,pair_Point)using pair_Point to divide points into two parts point_one[1-index-1] andpoint_two[index+1-2*N]Get_Pair(point_one[1-index-1])Get_Pair(point_two[index+1-2*N])elseget the line to connect this two pointsendifWe will prove this algorithm is O(n log n) time, first we get the deepest point in O(n) time, next we compute the other points with this deepest point 's angle in X axis in O(n) time, we use quick_sort to sort these n angles in O(n log n). Last we iterator these angles in O(n) to find the pair. So all time we consume is only O(n log n) time.Next we will prove this algorithm always can find the pair. Now we assume the deepest point stand for the Ghostbusters using mark=0, so above this point, we have n-1Ghostbusters(mark=0) and n Ghosts(mark=1). So we can sort n-1 0 and n 1 in whole arrangement, no matter how we sort, we can get a index in 1 , which before this 1 we have the same number of 0 and 1. We can replace this problem with a new problem, we have a road for (0,0) point to (n-1,n) point , we only can move the one step in the X or Y direction. No matter which road we have, we must cross the line Y=X it means we must get the Ghost. Before this ghost, we have the same number of ghosts and ghostbusters.Last, we will prove that solving this problem is O(n2 log n).Easily, we get the T(n)=2*T(n/2)+O(n log n).We use mathematical induction for assuming that T(n)<= O(n2 log n)n=1, T(1)=O(n log n)<=O(n2 log n)assume n<k T(n)<=O(n2 log n)then n=k, T(k)=2*T(k/2)+O(k log k)<=2*O(k2 log (k/2)/ 4)+O(k log k)=O(k2 log(k/2) /2)+O(k log k)<=O(k2 log k)2 Divide and ConquerYou are interested in analyzing some hard-to-obtain data from two separate databases. Each database contains n numerical values-so there are 2n values total-and you may assume that no two values are the same. You’d like to determine the median of this set of 2n values, which we will define here to be the n th smallest value.However, the only way you can access these values is through queries to the databases. In a single query, you can specify a value k to one of the two databases, and the chosen database will return the k th smallest value that it contains. Since queries are expensive, you would liketo compute the median using as few queries as possible.Give an algorithm that finds the median value using at most O(log n) queries.Answer:First we can assume the two arrays are in ascending order because in this question we can specify a value k to one of the two arrays, and this system will return the k’t h smallest value that it contains. So in the following two arrays: An and Bn. (each array contains n different value and is in ascending order)So we get the median of two arrays: A[n/2] and B[n/2]. Before the A[n/2] value, there are only n/2-1 values, the same , before the B[n/2] value, there are only n/2-1values.(A[n/2]!=B[n/2] because all 2n values are not same). So we only have two conditions: i: A[n/2]<B[n/2] , before the B[n/2] value, there must be at least n/2-1+n/2-1+1=n-1values(n/2-1 before A[n/2] and n/2-1 before B[n/2] and 1 stand for A[n/2] itself). The same , before the A[n/2] value, there must be at most n/2-1+n/2-1=n-2. So the two arrays’ median value must be in the interval A[n/2+1] to A[n] and in the interval B[1] to B[n/2]. We can divide this problem into one small problem . At last , A and B only have one value , we get the small one which is the result.ii: A[n/2]>B[n/2] , the same, the two arrays’ median value must be in the interval A[1] toA[n/2] and in the interval B[n/2+1] to B[n].Algorithm:Get_Median(A[1-n],B[1-n])If the A and B only have one element thenReturn the small oneElseGet the median a and b stand for A and BIf a<bReturn Get_Median(A[n/2+1-n],B[1-n/2])ElseReturn Get_Median(A[1-n/2],B[n/2+1-n])EndifEndifNow , we will prove this algorithm is O(log n) time.In algorithm: we can have T(n)=T(n/2)+c when n>1 and T(1)=c (c is the constant value) , So we get T(n)=clog n. Then this algorithm is O(log n) time.3 Divide and ConquerGiven a convex polygon with n vertices, we can divide it into several separated pieces, such that every piece is a triangle. When n = 4, there are two different ways to divide the polygon; When n = 5, there are five different ways.Give an algorithm that decides how many ways we can divide a convex polygon with n vertices into triangles.Answer:We get the f(n) to stand for : the number of different ways to divide the n-polygon.f(1)=1;f(n)=f(1)*f(n-1)+f(2)*f(n-2)+....+f(n-1)*f(1) n>1;So the algorithm is:int f(int n)If n==1return 1;Elseint result=0;for i=1 to n-1result+=f(i)*f(n-i);Endforreturn result;Endif4 Counting InversionsRecall the problem of finding the number of inversions. As in the course, we are given a sequence of n numbers a1, ..., a n, which we assume are all distinct, and we define an inversion to be a pair i < j such that a i > a j .We motivated the problem of counting inversions as a good measure of how different two orderings are. However, one might feel that this measure i s too sensitive. Let’s call a pair a significant inversion if i < j and a i > 3a j .Given an O(n log n) algorithm to count the number of significant inversions between two orderings.Answer:Given a sequence of n numbers , we use a array D[1-n] which contains this n numbers. We can use Sort_Count function in the normal CountingInversions. Assume we divide D[1-n] into two half array D1[1-n/2] for D[1-n/2] and D2[1-n/2] for D[n/2+1-n], and we have already sort the two arrays D1 and D2 and computed the inversions’ numbers. Now what we only should do is to get the D1[i] and D2[j] (i and j is 1-n/2) and look whether this two number is inversed and at the same time we should merge this two sorted array.Now let us describe this problem: we already get two sorted arrays D1[1-n/2] and D2[1-n/2], we set three indexes i and j1 and j2, i and j2 is to iterate D1 and D2, j1 is to .D2[j1-j2-1]<D1[i] in other word, it means the current i’th value is bigger th an j1 to j2-1’s all values. When we iterate i’th number in D1 and j’th number in D2, we have two conditions : (because all numbers are distinct , so D1[i]!=D2[j2])i: D1[i]<D2[j2]. We look whether D1[i] is treble than D2[j1] , if D1[i]>3*D2[j1] then we add InverseCount with the number of D1 remaining arrays . (InverseCount stand for the current number of inversions) and at the same time, we add j1 to look the next element in D2. Else, we insent D1[i] value into new sorted array and add i to look the next element in D1.ii: D1[i]>D2[j2]. We insert D2[j2] value into new new sorted array and add j2 to look the next element in D2.Algorithm:Merge_and_Count(D1[1-n],D2[1-n])Initial InverseCount , i, j1, j2 with 0Initial new array NEW_D which contains all elements in ascending orderWhile D1 and D2 all is not emptyIf D1[i]<D2[j2]If D1[i]>3*D2[j1]Add InverseCount with the number of D1’s remaining’s elementsIncrement j1ElseInsert D1[i] into NEW_DIncrement iEndifElseInsert D2[j2] into NEW_DIncrement j2EndifEndWhileWhile D2 is not emptyInsert D2[j2] into NEW_DIncrement j2EndWhileWhile D1 is not emptyIf j1 is not iterate to the end of D2If D1[i]>3*D2[j1]Add InverseCount with the number of D1’s remaining’s elementsIncrement j1ElseInsert D1[i] into NEW_DIncrement iEndifElseInsert D1[i] into NEW_DIncrement iEndifEndWhileReturn InverseCountSort_and_Count(l,r)If l<rGet middle m between l and rGet RCL is Sort_and_Count(l,m) which stand for the left half array ‘s inversion’s numberGet RCR is Sort_and_Count(m+1,r) which stand for the right half array’s inversion’s numberGet RLR is Merge_and_Count(D1[l-m],D2[m+1-r]) which stand for the left and right ‘s inversion’s numberReturn RCL+RCR+RLREndif5 Counting InversionsThe attached file Q5.txt contains 100,000 integers between 1 and 100,000 (each row has a single integer), the order of these integers is random and no integer is repeated.1. Write a program to implement the SORT-AND-COUNT algorithms in your favorite lan-guage, find the number of inversions in the given file.2. In the lecture, we count the number of inversions in O(n log n) time, using the MERGE-SORT idea. Is it possible to use the QUICK-SORT idea instead ?If possible, implement the algorithm in your favorite language, run it over the given file, and compare its running time with the one above. If not, give a explanation.Answer:1: C++ Code:#include<iostream>#include<fstream>#include<memory.h>#include<stdlib.h>using namespace std;int N=100000;int data[100000];ofstream out("res.txt");long long merge_count(int l,int m,int r){int count=0;int* L=(int*)malloc((m-l+1)*sizeof(int));int* R=(int*)malloc((r-m)*sizeof(int));//memcpy(L,data+l*sizeof(int),(m-l+1)*sizeof(int));//memcpy(R,data+(m+1)*sizeof(int),(r-m)*sizeof(int));for(int i=l;i<=m;i++)L[i-l]=data[i];for(int i=m+1;i<=r;i++)R[i-m-1]=data[i];int i=0,j=0,k=l;for(;i<m-l+1&&j<r-m;){if(L[i]>R[j]){data[k++]=R[j++];count+=m-l-i+1;}else{data[k++]=R[i++];}}for(;i<m-l+1;){data[k++]=L[i++];}for(;j<r-m;){data[k++]=R[j++];}return count;}long long inversion_Counting(int l,int r){if(l<r){int m=(l+r)>>1;long long L=inversion_Counting(l,m);long long R=inversion_Counting(m+1,r);long long LR=merge_count(l,m,r);out<<L+R+LR<<endl;return L+R+LR;}elsereturn 0;}int main(){ifstream in("Q5.txt");for(int i=0;i<N;i++)in>>data[i];cout<<inversion_Counting(0,N-1);return 0;}The result is 1693706111.2. We cannot use QUICK_SORT idea to implement the InverseCounting. Because we cannot have the two sorted half array. When we use Merge_Sort, we first get two sorted half array and can compute one number in left array and another number in right array. In fact, we do the Merge_Sort function is the same with visiting tree in postorder. But we do the Quick_Sort function is the same with visiting tree in preorder. Only in postorder, we first get the two half arrays(the node's two children) in order, so we can visit thenode itself.6 SortingThe M ERGE-S ORT, Q UICK-S ORT and M ODIFIED-Q UICK-S ORT algorithms in the lecture slides are all recursive. However, by using a stack, all of them can be implemented in a iterative way. 1. Implement both the recursive version and iterative version of the three algorithms inyour favorite language.2.Run your implementation over three integer arrays whose sizes are 100, 000, 1, 000, 000,10, 000, 000 respectively. Record their running times and make a comparison.Answer:with C++ code in Linux System using Eclipse:M ERGE-S ORT Q UICK-S ORT100, 00040ms 50ms1, 000, 000980ms 422ms10, 000, 00011486ms 4980msM ERGE-S ORT-Itr Q UICK-S ORT-Itr100, 000114ms 46ms1, 000, 0001306ms 547ms 10, 000, 00014765ms 6429ms。