Also, you'll see that they are all "regraded". That's because I had a canvas misunderstang which had them originally at 4 points each, and not the two that they should have been.
69 33 22 77 56 3 79 55 25 14After two passes of my sorting algorithm, the vector is:
22 33 69 77 56 3 79 55 25 14Which sorting algorithm am I using?
Answer: Insertion sort: The first pass sorts the first two elements, and the second pass sorts the first three elements.
73 61 20 84 81 37 57 88 77 1After two passes of my sorting algorithm, the vector is:
1 20 61 84 81 37 57 88 77 73Which sorting algorithm am I using?
Answer: Selection sort: The first pass swaps the minimum element (1) with the first element. The second pass swaps the second-minimum element (20) with the second element.
Suppose I am sorting the following vector using quicksort:
43 24 35 15 90 98 74 47 89 66 54If I am using the median-of-three pivot selection algorithm, what is the pivot? Answer: the median of 43, 98 and 54: 54.
You are sorting the following string using quicksort (those are lower-case L's, not ones):
l p g s v l f f f e b w lIf you use the first character as a pivot, what will the string be right before you make the first recursive call?
Answer: f l g b e f f l l v s w p. Remember, when you see an 'l', it needs to be swapped into the other set. You got 6 points if you forgot to swap the first element into place at the end (l l g b e f f f l v s w p). You got 5 points if you didn't swap the 'l' characters into the other set: (f b g e f l f l v s p w l). And you got 3 points if you didn't swap the 'l' characters, and you forgot to swap the first element: (l b g e f l f f v s p w l).
Canvas will show that this question has been "regraded'. That's because I originally forgot to set the "correct" answer. You received the correct number of points, but it wasn't showing the correct answer. The regrade fixed that.
The following list specifies the edges in an undirected, weighted graph with 10 nodes labeled A through J. In the answer box, please enter the edges in the minimum spanning tree of the graph. Specify an edge from X to Y as "XY" (but no quotes). You can separate your edges with spaces or put them on separate lines. Please don't put anything else in your answer except the edges.
Edge: AF -- weight 1 Edge: AJ -- weight 2 Edge: EH -- weight 4 Edge: FJ -- weight 5 Edge: EG -- weight 6 Edge: GH -- weight 8 Edge: EF -- weight 9 Edge: BI -- weight 10 Edge: CD -- weight 12 Edge: GJ -- weight 14 Edge: FH -- weight 15 Edge: AE -- weight 17 Edge: HJ -- weight 18 Edge: AG -- weight 20 Edge: EJ -- weight 21 Edge: CI -- weight 22 Edge: BD -- weight 23 Edge: FG -- weight 25 Edge: AH -- weight 26 Edge: BC -- weight 27 Edge: DI -- weight 29 Edge: DF -- weight 31 Edge: AI -- weight 32 Edge: DE -- weight 33 Edge: HI -- weight 34 Edge: CE -- weight 36 Edge: AC -- weight 37 Edge: AD -- weight 38 Edge: FI -- weight 39 Edge: EI -- weight 40Answer: Since the edges are sorted, Kruskal's algorithm is straightforward. Here are the edges and the components. If a node is not listed, it's in its own component:
AF -- AF AJ -- AFJ EH -- AFJ EH FJ -- skip EG -- AFJ EGH GH -- skip EF -- AEFGHJ BI -- AEFGHJ BI CD -- AEFGHJ BI CD GJ -- skip FH -- skip AE -- skip HJ -- skip AG -- skip EJ -- skip CI -- AEFGHJ BCDI BD -- skip FG -- skip AH -- skip BC -- skip DI -- skip DF -- ABCDEFGHIJ -- we're done and and skip the rest.So the answer is: AF AJ EH EG EF BI CD CI DF.
Grading: I counted the number of "wrong" answers. This starts with the size of your answer minus 9 (minimum value = 0). To this, I added the number of correct answers that weren't in your answer. Perfect answer is 8 points. If there were any wrong, then you got 9 - wrong*2. Minimum score is zero.
Below is a specification of a directed, unweighted graph using adjacency lists. In the answer box, please give a listing of the nodes in the order of a valid topological sort. There may be many valid answers -- you only have to give one valid answer. Please answer by simply listing the nodes. You don't need spaces or commas or newlines between the nodes, but it's ok to do to. In fact, if the browser lets you, I'd recommend cutting and pasting the adjacency lists into your answer and then working through it from there. But that's me.
Please don't put any other stray stuff like numbers or comments in your answer. Remember that you can resize your entry window if it makes your life easier.
A: D C B: D H A C: D: E: C F: D B G: H C B H: I: D H C A J: A I G E FAnswer: Make yourself a vector of incoming edges, and then keep removing nodes with no incoming edges from the graph. I'll mark a node with x when it's done.
Incoming-Edges Node-To-Remove A B C D E F G H I J 3 2 4 4 1 1 1 3 1 0 J 2 2 4 4 0 0 0 3 0 x E (You can remove any of E, F, G, I) 2 2 3 4 x 0 0 3 0 x F (You can remove any of F, G, I) 2 0 2 3 x x 0 2 0 x G (You can remove any of B, G, I) 2 0 2 3 x x x 2 0 x I (You can remove any of B, I) 1 0 1 2 x x x 1 x x B 0 x 1 1 x x x 0 x x A (You can remove any of A, H) x x 0 0 x x x 0 x x H (You can remove any of C, D) x x 0 0 x x x x x x C (You can remove any of C, D) x x x 0 x x x x x x D (You can remove any of C, D)So a valid answer is JEFGIBAHCD. Any legal answer got full credit.
Grading: As above, I counted the number of "wrong" answers. This starts 10 minus the number of nodes that you gave. If you gave more than 10 nodes, then it started at zero. Then I performed the topological sorting calculation on your nodes, and whenever you gave an illegal node, I incremented the number of "wrong" answers. For example, suppose above you started with "A". That would be a wrong answer, because "A" has incoming edges. Regardless of whether your answer was right or wrong, I then deleted it from the tree.
Perfect answer is 8 points. If there were any wrong, then you got 9 - wrong*2. Minimum score is zero.
You are looking to find the max flow and min cut in the following graph:
After you have processed it, the final residual graph has the following edges:
In the box below, enter the maximum flow on the first line (just a number). And then enter the minimum cut on the next lines, one edge per line. No spaces; no punctuation. Use, for example, SA to represent the edge from S to A.
Answer: First do a DFS from S to identify the nodes that are reachable from S. Those are nodes S, B and D. The minimum cut is composed of the edges from those nodes to the others in the original graph: BA and CE. The maximum flow is equal to the sum of the weights of those two edges: 7+5 = 12.
Grading: Two points if you got an edge right. Two points if you got the flow right. Two points if you got the edges exactly right.
A B C D E F G H A | 0 67 57 44 59 11 42 36 B | 68 0 50 13 2 67 55 30 C | 53 62 0 3 49 34 5 23 D | 55 18 46 0 13 25 30 26 E | 27 57 23 69 0 42 8 55 F | 59 50 61 65 45 0 66 39 G | 44 2 66 34 44 61 0 60 H | 63 25 38 10 68 11 18 0You are in the middle of doing a shortest path calculation with Dijkstra's algorithms. You are maintaining a vector of the best known shortest paths, and the multimap that is central to Dijkstra's algorithm. The values of these data structures are as follows:
A B C D E F G H Best: 68 0 50 13 2 67 55 30 Multimap: key: 2 val: E key: 13 val: D key: 30 val: H key: 50 val: C key: 55 val: G key: 67 val: F key: 68 val: AYour job is to tell me what the state of these two data structures is after the next pass of Dijkstra's algorithm. What you should do is copy-and paste the two data structures above into your answer window, and then modify them to reflect the next pass of Dijkstra's algorithm. If the cut-and-paste doesn't have your answer be in a fixed-width font, set the "Paragraph" field of your entry box to "preformatted".
Answer: You are adding E to your "known" set of nodes. You remove it
from the multimap, and then you process
its edges to see if you improve any "best" paths to other nodes. E's row of the adjacency
matrix is:
A B C D E F G H
E | 27 57 23 69 0 42 8 55
So the paths to all of these nodes by going through E are:
A B C D E F G H
E | 29 59 25 71 - 44 10 54
The paths to A, C, F and G are all improved. So the "Best" vector becomes:
A B C D E F G H
Best: 29 0 25 13 2 44 10 30
And the multimap becomes:
key: 10 val: G
key: 13 val: D
key: 25 val: C
key: 30 val: A
key: 30 val: H
key: 44 val: F
Grading: In the "best" vector, I subtracted your number of mismatches from 6 and added half of that to your score (it couldn't be negative). Then with the multimap, if yours was too big, I set w to be the difference between yours and the correct one. Otherwise w was zero. I added one to w for every correct entry in the multimap that was not in yours. I divided w by the size of the correct multimap, and multiplied that by four, and added that to your score.
The GF(64K) graph is an unweighted, directed graph, where every node is labeled by a number from 0 to 0xffff. Every node with a label of i has two outgoing edges:
Write a procedure with the following prototype:
int shortest_path(int from, int to); |
You don't have to error check -- you will be guaranteed that from and to are numbers between 0 and 0xffff. Your program should return the length of the shortest path from from to to in the GF(64K) graph. You'll note that there is always a path between every pair of nodes, so you don't need to worry about from and to being disconnected.
Now, you can design this program as you'd like, but were this me, I'd implement this in one of two ways:
In your answer, set the "paragraph" field to "preformatted", which makes your code more readable. Also, you can resize that window so that you can see more than three lines.
Answer>: This is a BFS where you simply create the edges on the fly. You start by putting the "from" node onto a deque. And then you process the deque from the front until you process the "to" node. In the vector or map, you maintain the shortest known paths. Since there are only 64K entries, the vector doesn't take much space. Here's my solution:
#include <vector> #include <deque> #include <iostream> using namespace std; int shortest_path(int from , int to) { vector <int> paths; // This is where I store the best paths so far. deque <int> bfsq; // This is my breadth-first search queue int eto; // This is where I calculate the "to" node of edges. int i, n; /* Initialization: Set the best path length for each node to -1. Then set the path length for the first node to 0, and put the first node on the queue. */ paths.resize(1 << 16, -1); paths[from] = 0; bfsq.push_back(from); /* Process the queue. */ while (!bfsq.empty()) { /* Remove the first node on the queue, and if it's the destination, we're done. */ n = bfsq[0]; bfsq.pop_front(); if (n == to) return paths[n]; /* Generate the edges -- the "to" node of the two edges is the variable eto. */ for (i = 0; i < 2; i++) { switch (i) { case 0: eto = (n + 1) & 0xffff; break; case 1: eto = n << 1; if (eto & 0x10000) eto ^= 0x1100b; break; } /* If the "to" node is not on the queue yet, put it there with the proper path length */ if (paths[eto] == -1) { paths[eto] = paths[n] + 1; bfsq.push_back(eto); } } } /* This won't happen, but may as well keep the compiler quiet. */ return -1; } int main() { int from, to; cin >> from >> to; cout << shortest_path(from, to) << endl; return 0; } |
Grading: If you had the right structure for a BFS, you started with 12 points and had deductions. If you didn't do a BFS, you typically started with 6 points and had deductions. One deduction that was very frequent was "exponential blow up", which is what happens when you don't check to see if a node is already on the queue.
The following is a definition for a B-String:
[] [()] [[][]] [([]({}))]These are not B-strings:
[][] -- You can only have two concatenated strings inside a {, [ or ( [()()()] -- You can't have three strings inside a [] [[]] -- If you have one string inside a [], it cannot start with [Write a dynamic program (obviously, in C++) that reads n from standard input, and prints the total number of B-Strings that are n characters in length. You only need to go to "step 2" in the four steps of dynamic programming.
Some examples:
UNIX> echo 1 | a.out 0 UNIX> echo 2 | a.out 3 UNIX> echo 3 | a.out 0 UNIX> echo 4 | a.out 6 # These are ([]), ({}), [()], [{}], {[]}, {()} UNIX> echo 6 | a.out 39 # 13 begin with [, 13 begin with {, 13 begin with ( UNIX>
Please feel free to cut and paste the following to get you started:
#include <string> #include <vector> #include <iostream> using namespace std; class Bstring { public: vector < vector <long long> > Cache; long long bs(int len, int potential_starting_chars); }; long long Bstring::bs(int len, int psc) { // Do base cases. // Create the cache if you need to. // Check the cache // You have two cases to count: strings like { T }, and strings like { TS }. } int main() { int len; Bstring b; cin >> len; cout << b.bs(len, 3) << endl; return 0; }Answer: This is a straightforward dynamic program that treats the two cases recursively. Please see the comments inline:
#include <vector> #include <iostream> using namespace std; class Bstring { public: vector < vector <long long> > Cache; long long bs(int len, int potential_starting_chars); }; /* My main recursive method is bs(len, psc), where psc is either 3 or 2, depending on whether there are 3 or 2 potential starting characters. It returns the number of bstrings of length len that has that many potential starting characters. On second thought -- this really makes the problem harder than it needs to be. You can instead just have bs(len), and then if you only have two potential starting characters, you multiply the answer by 2/3. Still, this is the first answer that came to me. My DP cache is indexed on len and psc-2. */ long long Bstring::bs(int len, int psc) { long long total; size_t i; /* If there's no cache, create it and set all of the entries to -1. */ if (len > Cache.size()) { Cache.resize(len+1); for (i = 0; i < Cache.size(); i++) Cache[i].resize(2, -1); } /* Handle the base cases. I handle two explicitly, because the recursion won't work with two, since bs(0,x) returns 0. */ if (len <= 0) return 0; if (len == 2) return psc; if (len % 2 == 1) return 0; /* Check the cache and return it if it's there. */ if (Cache[len][psc-2] != -1) return Cache[len][psc]; /* Do the recursive calculation. */ total = 0; total += (psc * bs(len-2, 2)); // This handles the {T}/[T]/(T) case. for (i = 2; i < len-2; i += 2) { // This handles the {TS}/[TS](TS) case. total += (psc * bs(i, 3) * bs(len-i-2, 3)); } /* Put the answer into the cache and return it. */ Cache[len][psc-2] = total; return total; } int main() { int len; Bstring b; cin >> len; cout << b.bs(len, 3) << endl; return 0; } |
Grading: You typically started with 8 points for having the base cases right, cache management right and some recursion. There were deductions when you got the base cases incorrect, or you didn't initialize the cache.
If you calculated "{T}" correctly, but not "{TS}", you received 5 more points.
The rest of the points were deductions or additions, and there are too many to list.