## CS302 Midterm, Fall, 2015

### Question 1: 15 points

This was the question on which the class did the worst. Everything comes from the enumeration lecture notes.
• Part A: The loop will go from 0 to (25-1), printing out "yes" once for every number that has the second least significant bit set. Half of the 32 numbers have this bit set, and half don't, so there will be 16 lines printed.
• Part B: The loop will go from 0 to (28-1), printing out "yes" once for every odd number (where i & 1 equals one). That will be 128 lines.
• Part C: The loop will go from 0 to 7, but it won't print out any lines, because (1 << 3) equals eight, and is bigger than all of those numbers.
• Part D: This is the number of permutations of the numbers 2,3,4,5,6,7 (because you always start at city 1). That is 6! = 6*5*4*3*2 = 720.
• Part E: There are "75 choose 4" ways to choose the running backs and "32 choose 2" ways to choose the quarterbacks. That is:

(75!)/(4!71!) * (32!)/(2!30!) = 75*74*73*72*32*31 / (4*3*2*2)

• Part F: We enumerated three-letter passwords, where each letter was a lower-case letter. That's 263.
• Part A: Two points. I gave 1 point for 32 or 15, and a half a point for 31. 16 was the most popular answer, followed by 8 and 32.
• Part B: Two points. I gave 1 point for 256 or 127, and a half a point for 255. 128 was the most popular answer, followed by zero and 256.
• Part C: Two points. I gave half a point for 4 and 1, and a quarter of a point for 8, 7 and 3. Zero was the most popular answer, followed by 1 and 4.
• Part D: Three points. I gave 1.75 points for 7*6*5*4*3*2 = 5040 and for answering "6,!" which was not following the instructions. You got one point for "7!". 5040 was the most popular answer here, followed by "7!" and then 720.
• Part E: Three points. I gave you 1.75 points if you only gave me the numerator, and 1.5 points if you didn't follow the instructions, and gave me the combinatorics without multiplying it out. The correct answer was the most popular, followed by "numerator only." A lot of students answered things like "754+322." If you are one of those students, you should reread the lecture notes on this topic. I also had this be part of a monday lab.
• Part F: Three points. I gave you two points for 273, and half credit for n3. The majority of students got this one correct!

### Question 2: 15 points

• A: Straight from the lecture notes: O(n2): g.
• B: This should be etched in your blood: O(n log(n)): i.
• C: This copies the string: O(n): d.
• D: Straight from the lecture notes: O(n): d.
• E: This just requires traversing the map and calling push_back(): O(n): d.
• F: Because m is less than n, this will be O(n log(n)): i. Think about it. If m is two, and n is 1000, then the dominating cost will be n, not m.
• G: This simply sets s2 to a pointer: O(1): a.
• H: Again, n is bigger than m, so each Pop() is O(log (n)). Therefore, the answer is O(m log(n)): l.
• I: Straight from the lecture notes: O(n2): g.
• J: You start with rbegin() and increment a reverse iterator m times. Each of those operations is constant time, so this is O(m): e.
• K: Straight from the lecture notes: O(n): d.
• L: To do this, you would do an upper_bound() call, which is O(log(n)), and then increment and decrement iterators around the return value, which is O(m): r.
• M: Each of these is O(log(n)), so: O(m log(n)): l.
• N: Each of these is O(log(n)), so: O(m log(n)): l.
• O: With selection sort, you have to look for the minimum element on each pass, and there is no benefit to having the vector already sorted: O(n2): g.

• 1 point per part.
• You get 0.5 points for answering k on part F.
• You get 0.5 points for answering j on part H.
• You get 0.2 points for answering r on part J.
• You get 0.3 points for answering l on part L.
• You get 0.3 points for answering j on part N.
This was one of the few times that crowdsourcing didn't get every answer correct. Parts F and L tripped y'all up, as they required some precise thought and understanding of big-O:

 a b c d e f g h i j k l m n o p q r s t u v w x y z A 0 1 0 3 0 0 61 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 B 0 15 0 5 0 0 1 0 47 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 C 17 0 0 31 4 6 0 0 0 1 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 D 0 3 0 53 0 0 0 0 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 E 1 8 0 48 0 1 1 0 9 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 F 0 2 0 1 0 2 0 0 2 2 58 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 G 26 1 2 16 7 6 1 1 0 0 1 0 0 1 0 1 1 0 5 0 0 0 0 0 0 0 H 0 0 1 1 3 2 0 0 0 1 1 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 I 0 2 0 0 0 0 63 0 1 0 0 1 0 0 0 0 0 0 0 0 0 2 0 0 0 0 J 0 0 2 5 25 12 0 0 0 0 0 20 1 0 0 0 0 3 0 0 0 0 0 1 0 0 K 1 5 0 55 0 0 5 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 L 0 0 1 2 5 7 0 0 0 2 1 40 1 0 0 0 0 9 0 0 0 0 0 1 0 0 M 0 1 1 0 1 1 0 0 0 1 0 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 N 0 1 1 0 2 4 0 0 0 0 0 60 0 0 0 0 0 1 0 0 0 0 0 0 0 0 O 0 5 0 9 0 0 52 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0

### Question 3: 15 points

 A-1: No: A-2: Yes: A-3: Yes: A-4: No:

Part B:

Part C:

• 2 points for each part of A
• 3 points for part B
• 4 points for part C

### Question 4: 14 points

Selection sort:

 Pass Action Result Letter 1 Swap 10 with 10 (do nothing) 10, 47, 99, 64, 77, 35, 56, 21 w 2 Swap 21 with 47 10, 21, 99, 64, 77, 35, 56, 47 j 3 Swap 35 with 99 10, 21, 35, 64, 77, 99, 56, 47 g 4 Swap 47 with 64 10, 21, 35, 47, 77, 99, 56, 64 e 5 Swap 56 with 77 10, 21, 35, 47, 56, 99, 77, 64 d 6 Swap 64 with 99 10, 21, 35, 47, 56, 64, 77, 99 a 7 Swap 77 with 77 (do nothing) 10, 21, 35, 47, 56, 64, 77, 99 a 8 Done 10, 21, 35, 47, 56, 64, 77, 99 a

Insertion Sort

 Pass Action Result Letter 1 Insert 47 (do nothing) 10, 47, 99, 64, 77, 35, 56, 21 w 2 Insert 99 (do nothing) 10, 47, 99, 64, 77, 35, 56, 21 w 3 Insert 64 10, 47, 64, 99, 77, 35, 56, 21 v 4 Insert 77 10, 47, 64, 77, 99, 35, 56, 21 u 5 Insert 35 10, 35, 47, 64, 77, 99, 56, 21 o 6 Insert 56 10, 35, 47, 56, 64, 77, 99, 21 n 7 Insert 21 10, 21, 35, 47, 56, 64, 77, 99 a

• Selection sort: 1.1 points for w and a, 1.2 points for j, g, e and d. -1 point for incorrect answers.
• Insertsion sort: 1.1 points for w and a, 1.2 points for v, u, o and n. -1 point for incorrect answers.

### Question 5: 15 points

The easiest thing to do, of course, is Union by Size. The constructor is O(n), Union() is O(1), and Find() is O(log n). The other two implementations are in the lecture notes (with this one).

 ```Disjoint::Disjoint(int nelements) { links.resize(nelements, -1); ranks.resize(nelements, 1); } int Disjoint::Union(int s1, int s2) { int p, c; if (ranks[s1] >= ranks[s2]) { p = s1; c = s2; } else { p = s2; c = s1; } links[c] = p; ranks[p] += ranks[c]; return p; } int Disjoint::Find(int element) { while(links[element] != -1) element = links[element]; return element; } ```

• Constructor: Three points.
• Find: Three points.
• Union: Four points, partitioned into:
• DP - Determining parent.
• UR - Updating ranks.
• RV - Return value.
• Naming the implementation. If you wrote "union by rank" or "path compression," but you didn't actually implement path compression, then you did not get credit for this.
• Constructor running time: Linear
• Union running time: Constant
• Find running time: Log, unless you implemeneted union by rank with path compression, in which case it was O(α(n)).

### Question 6: 15 points

Here it is with a main() stuck on it so you can test it. This was identical to a program that I gave you in a monday lab.

 ```#include #include #include using namespace std; long long two_ks(int K, long long S) { long long rv; if (K == 0) return 1 % S; if (K%2 == 1) return (2 * two_ks(K-1, S)) % S; rv = two_ks(K/2, S); return (rv * rv) %S; } main() { int K; long long S; cin >> K >> S; cout << two_ks(K, S) << endl; exit(0); } ```