## CS302 Midterm, Fall, 2013

### Question 1: 10 points

This is permutation code, straight from the lecture notes, except I'm permuting integers rather than strings. Also, I'm starting the permutation with index 1, so the 10 will never be moved from slot 0. Since we are permuting 5 elements (the 10 never moves), there will be 5! lines printed.
```UNIX> a.out | head -n 6
10 11 12 13 14 15
10 11 12 13 15 14
10 11 12 14 13 15
10 11 12 14 15 13
10 11 12 15 14 13
10 11 12 15 13 14
UNIX> a.out | wc
120     720    2280
UNIX>
```
The answers are g and a

Part 1: 5 points for g. Three points for e or h.

Part 2: 5 points for a. Three points for b.

### Question 2: 12 points

These are all straight from the lecture notes. Grading is 1.5 points each.
• A. Deleting an element from a map with n elements: O(log(n))
• B. Constructing a heap from a vector with n elements: O(n)
• C. Performing union() on a disjoint set instance with n elements: O(1)
• D. Performing find() on a disjoint set instance with n elements: O(α(n))
• E. Performing upper_bound() on a map with n elements: O(log(n))
• F. Inserting an element into a map with n elements: O(log(n))
• G. Performing pop() on a heap with n elements: O(log(n))
• H. Performing push() on a heap with n elements: O(log(n))

### Question 3: 10 points

This is pretty straightforward bit arithmetic. Since the integer is less than 108, it is easily less than 230. In the code below, I calculate the largest digit that is set, and then go from that digit down to the smallest digit, adding either a '0' or a '1' to the string:

 ```string bits(int n) { int md, i; string rv; md = 0; for (i = 1; i < 31; i++) { if ( (1 << i) & n ) md = i; } for (i = md; i >= 0; i--) { if ( (1 << i) & n ) rv.push_back('1'); else rv.push_back('0'); } return rv; } ```

In q3.cpp, I've added main(), which reads from standard input, and prints the result of bits().

10 points. I grade these pretty much on how well I think your solution addressed the problem. I did deduct for the following problems:
• Doesn't handle zero.
• Called push_back() with a string instead of a char.

### Question 4: 12 Points

• A: 20
• B: There are four elements whose links are -1, so 4.
• C: 20 - 4 = 16
• D: Since links of 1, 4 and 8 are 0, the size of set 0 is at least 4. Since ranks[0] equals 2, it cannot be holding the size.
• E: Set 0 = 4. Set 2 = 13. Set 11 = 2. Set 12 = 1.
• Call find(e) when e equals 9, 13, 14, 16, 18 or 19. If the implementation uses path compression, then after the find() call, ranks[e] will equal 2. Otherwise, it will be unchanged.

10 points. I grade these pretty much on how well I think your solution addressed the problem. I did deduct for the following problems:
• A, B, C: one point each.
• D: two points.
• E: four points
• F: three points.

### Question 5: 10 Points

• A: Straight from the lecture notes: (i-1)/2 (integer division): Two points
• B: 2i+1 and 2i+2: Two points
• C: { 8, 9, 66, 29, 27, 93, 71, 36, 78, 75, 58 }: Three points

• D: { 27, 29, 66, 36, 58, 93, 71, 75, 78 }: Three points

### Question 6: 12 Points

This one was nearly identical to the Topcoder problem that I assigned in lab: TCCC 2005, 250-Pointer (Fairness). I had hints for that program in http://web.eecs.utk.edu/~plank/plank/classes/cs302/Topcoder/Fairness.html, although since this program has no constraints, you can't do the second solution. Instead, you need to have a map keyed on the averages, whose second's are vectors of names. When you insert an average into the map, you call push_back() to put the name onto the vector.

 ```#include #include #include #include using namespace std; main() { string s; map > m; map >::iterator mit; double t, n, avg; int i; while (cin >> s) { t = 0; n = 0; for (i = 0; i < s.size(); i++) { n++; t += s[i]; } avg = t/n; m[avg].push_back(s); } for (mit = m.begin(); mit != m.end(); mit++) { for (i = 0; i < mit->second.size(); i++) { cout << mit->second[i] << endl; } } exit(0); } ```