Grading: 2 points per part. I gave some partial credit. In the grading, I abbreviated, so an answer of "n" is reallly O(n). Abbreviations which may not be as clear:
![]() |
Convert to Tree:![]() |
Add 3 as the last node:![]() |
Percolate Up:![]() |
The answer is:
3 29 5 47 50 28 60 84 59 83 72 86 |
Convert to Tree:![]() |
Delete the last node and move it to the root:![]() |
Percolate Down:![]() |
The answer is:
25 35 31 43 38 62 94 83 82 90 |
View unsorted vector as a tree:![]() |
Percolate down with 69 and 90:![]() |
Percolate down with the root:![]() |
The answer is:
10 31 73 78 69 87 90 |
Node: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Links: 1 -1 0 1 1 -1 1 -1 11 0 1 -1 11 -1 0 -1 Sizes: 4 9 1 1 1 1 1 1 1 1 1 3 1 1 1 1 |
Node: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Links: 23 11 16 0 23 23 23 23 23 13 13 23 23 23 16 10 23 23 19 13 4 7 23 -1 -1 Ranks: 2 1 1 1 2 1 1 2 1 1 2 2 1 3 1 1 2 1 1 2 1 1 1 4 1 |
80 64 61 66 47 4 51 56 40 3 64 61 66 47 4 51 56 40 3 80 61 64 47 4 51 56 40 3 66 80 |
12 40 46 92 77 54 59 82 87 83 |
13 60 73 85 88 62 9 10 65 86 |
![]() |
int g(int x)
{
int y, z, gz;
/* Start with the base case. */
if (x == 0) return 1;
/* Find y using bit arithmetic. since x <= 1024, the 10th bit is the highest
one that can be set, so start with y = 11. */
for (y = 11; y >= 0; y--) {
if (x & (1 << y)) {
/* At this point, you have found y. You can calculate z by either
"clearing" the bit with and-not, or simply by subtracting (1 << y): */
z = x - (1 << y); // This works too: z = x & ( ~(1 << y) );
/* Make the recursive call, and return the result. */
gz = g(z);
return y * (gz + z);
}
}
/* You didn't have to do this, but if x is not in the right range, let's return -1. */
return -1;
}
|
Grading: 16 points. You got 4 points for getting the base case right, and four points for the recursion. The remainder of the points were on the bit arithmetic.
![]() |
Here's the code, commented with what's going on:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
long long n;
long long top;
long long val, i, copy;
string dna = "ACGT";
cin >> n;
/* First calculate 4^n */
top = 1;
for (i = 0; i < n; i++) top *= 4;
/* Enumerate every value from 0 to 4^n-1 */
for (val = 0; val < top; val++) {
/* Make a copy, and treat copy as a number
in base four -- extract each digit, which
will be a value from 0 to 3, and use it to
print the character of the DNA sequence. */
copy = val;
for (i = 0; i < n; i++) {
printf("%c", dna[copy%4]);
copy /= 4;
}
printf("\n");
}
return 0;
}
|
Grading: 16 points. You got a point for reading n, three points for calculating 4^n correctly, three points for your loop, two points for copying the loop variable so that you could do the div/mod enumeration, 6 points for the div/mod/character extraction, and one point for printing.
![]() |
The strategy is to make a map of the restaurants, where the key is the position and the val is the number of occupants. Then, for each car, you call upper_bound() or lower_bound(), to find the restaurants whose positions are the closest greater than or less than (or equal to) the car. Update the occupants in the closer restaurant. At the end, print out the map.
You should sentinelize the map, so that there's a restaurant far less than the smallest, and far greater than the greatest. Then you don't need to worry about what happens when lower_bound() returns end() or begin().
The code is in q5.cpp. I've just included Occupants(). The code has a main() with the example from the problem writeup.
#include <map>
#include <vector>
#include <iostream>
#include <cstdio>
using namespace std;
void Occupants(vector <double> &Rpos, // Positions of the restaurants
vector <double> &Cpos, // Positions of the cars
vector <int> &Cocc) // Occupants of the cars
{
map <double, int> R; // Key = position, val = # occupants
map <double, int>::iterator hit;
map <double, int>::iterator lit;
int i;
/* Put each restaurant, with zero occupants, into the map. */
for (i = 0; i < Rpos.size(); i++) R[Rpos[i]] = 0;
/* Sentinelize the map with two fake restaurants. One should
have a value so small that a car will never go to it, and one
should have a value so big that a car will never go to it. */
R[-30000] = -1;
R[30000] = -1;
/* For each car, find the closest restaurant whose position is less,
and the closest restaurant whose position is greater than or equal
to the car. Put the occupants from the car into the restaurant. */
for (i = 0; i < Cpos.size(); i++) {
hit = R.lower_bound(Cpos[i]);
lit = hit;
lit--;
if (hit->first - Cpos[i] < Cpos[i] - lit->first) {
hit->second += Cocc[i];
} else {
lit->second += Cocc[i];
}
}
/* Print out the restaurants. Ignore the two sentinels. */
for (hit = R.begin(); hit != R.end(); hit++) {
if (hit->second != -1) {
printf("%9.2lf %d\n", hit->first, hit->second);
}
}
}
|
Grading: 16 points. You got four points for creating the map correctly, two points for lower-bound (or upper-bound), four points for the comparison of each car to two restaurants, two points for handling the edge cases, and four points for your ending loop.
![]() |