ACM notes • Sometimes a problem is much more difficult than expected! strategize as a team to find an algorithm • Basic approach: implement (1 or 2 people coding) debugging Sigma problem 1 1 1 1 1 1 1 2 2 2 2 2 2 2 3 4 4 4 4 4 4 8 6 8 8 8 9 9 17 34 68 77 16 32 64 80 16 24 28 29 58 87 16 32 33 66 99 stated answers 1 1 1 1 1 1 1 2 2 2 2 2 2 2 3 4 4 4 4 3 3 8 5 8 6 6 9 9 18 36 72 77 16 32 64 80 12 24 48 72 84 87 12 24 48 96 99 better answers Change const int p=1,n=5,d=10,q=25,h=50; int counter=0; int pn, nn, dn, qn, hn; for (hn = 0; hn*h <= num; hn++) for (qn = 0; hn*h + qn*q <= num; qn++) for (dn = 0; hn*h + qn*q + dn*d <= num; dn++) for (nn = 0; hn*h + qn*q + dn*d + nn*n <= num; nn++) for (pn = 0; hn*h + qn*q + dn*d + nn*n + pn*p <= num; pn++) { if (hn*h + qn*q + dn*d + nn*n + pn*p == num) counter++; } Brute Force Dynamic Programming using 1¢ total 1¢, 5¢ 1¢, 5¢, 10¢ 0¢ 1¢ 2¢ 3¢ 4¢ 5¢ 6¢ 7¢ 8¢ 9¢ 10¢ 11¢ 12¢ Change const int p=1,n=5,d=10,q=25,h=50; int counter=0; int pn, nn, dn, qn, hn; for (hn = 0; hn*h <= num; hn++) for (qn = 0; hn*h + qn*q <= num; qn++) for (dn = 0; hn*h + qn*q + dn*d <= num; dn++) for (nn = 0; hn*h + qn*q + dn*d + nn*n <= num; nn++) for (pn = 0; hn*h + qn*q + dn*d + nn*n + pn*p <= num; pn++) { if (hn*h + qn*q + dn*d + nn*n + pn*p == num) counter++; } Brute Force Dynamic Programming 0¢ 1¢ 2¢ 3¢ 4¢ 5¢ 6¢ 7¢ 8¢ 1 1 1 1 1 1 1 1 1 1 1¢, 5¢ 1 1 1 1 1 2 2 2 2 2 1¢, 5¢, 10¢ 1 1 1 1 1 2 2 2 2 2 using 1¢ total 9¢ 10¢ 1 11¢ 12¢ Change const int p=1,n=5,d=10,q=25,h=50; int counter=0; int pn, nn, dn, qn, hn; for (hn = 0; hn*h <= num; hn++) for (qn = 0; hn*h + qn*q <= num; qn++) for (dn = 0; hn*h + qn*q + dn*d <= num; dn++) for (nn = 0; hn*h + qn*q + dn*d + nn*n <= num; nn++) for (pn = 0; hn*h + qn*q + dn*d + nn*n + pn*p <= num; pn++) { if (hn*h + qn*q + dn*d + nn*n + pn*p == num) counter++; } Brute Force Dynamic Programming 0¢ 1¢ 2¢ 3¢ 4¢ 5¢ 6¢ 7¢ 8¢ 1 1 1 1 1 1 1 1 1 1 1 1¢, 5¢ 1 1 1 1 1 2 2 2 2 2 add 1¢, 5¢, 10¢ 1 1 1 1 1 2 2 2 2 2 using 1¢ total 9¢ 10¢ 11¢ 12¢ Change const int p=1,n=5,d=10,q=25,h=50; int counter=0; int pn, nn, dn, qn, hn; for (hn = 0; hn*h <= num; hn++) for (qn = 0; hn*h + qn*q <= num; qn++) for (dn = 0; hn*h + qn*q + dn*d <= num; dn++) for (nn = 0; hn*h + qn*q + dn*d + nn*n <= num; nn++) for (pn = 0; hn*h + qn*q + dn*d + nn*n + pn*p <= num; pn++) { if (hn*h + qn*q + dn*d + nn*n + pn*p == num) counter++; } Brute Force Dynamic Programming 0¢ 1¢ 2¢ 3¢ 4¢ 5¢ 6¢ 7¢ 8¢ 1 1 1 1 1 1 1 1 1 1 1 1 1 1¢, 5¢ 1 1 1 1 1 2 2 2 2 2 3 3 3 1¢, 5¢, 10¢ 1 1 1 1 1 2 2 2 2 2 4 4 4 using 1¢ total 9¢ 10¢ 11¢ 12¢ Prime numbers Check for divisibility by integers up to the square root of N. Or, just count factors... 2 3 4 5 Bug of the week: int* factorTable = new int[1000000]; 6 7 Prime suspects 8 9 10 #define MAXFAC 1000005 int fac[MAXFAC]; Problems Entropy bits used in ASCII Input Output AAAAABCD 64 13 4.9 bits used in an optimal “prefix-free” encoding compression ratio, to 1 place of precision Problems Entropy bits used in ASCII Input Output AAAAABCD 64 13 4.9 bits used in an optimal “prefix-free” encoding A B 0 10 C D 110 111 compression ratio, to 1 place of precision Problems N-Credible Mazes dimensions 2 Input start Output end Maze #1 can be travelled 0 0 2 2 (or not…) edge start 0 0 0 1 0 1 0 2 0 2 1 2 0 2 0 3 1 2 2 2 -1 edge end www.dinkumware.com/htm_cpl/index.html set #include <set> C++ STL www.sgi.com/tech/stl/ set<int> s; // basically a bin. tree s.size(); // returns an int s.insert(14); // adds 14 s.insert(-9); // adds -9 s.insert(42); // adds 42 set<int>::iterator i; // may want to typedef // think of an iterator as a pointer i = s.find(42); multiset #include <set> // return 42’s iterator cout << (*i) << endl; // prints 42 cout << (*--i)); // prints ... i = s.find(43); // not there ! // at this point ( i == s.end() ) is true s.erase(-9); // removing elements multiset<int> m; // holds multiple copies Breadth-first search • algorithm data structures queue, deque, hashtable (map) www.dinkumware.com/htm_cpl/index.html vector #include <vector> sort #include <algorithm> C++ STL www.sgi.com/tech/stl/ vector<int> v; // basically an int array v.reserve(10); // assure 10 spots v.push_back(42); // adds 42 to the end v.back(); // returns 42 v.pop_back(); // removes 42 v.size(); // # of elements v[i]; // ith element sort( v.begin(), v.end() ); // default sort sort( v.begin(), v.end(), mycompare ); last time deque #include <deque> deque<int> d; // double-ended queue d.push_front(42); // add to front d.front(42); // return front element d.pop_front(42); // remove from front Other problems • Change counting input: 1.00 output: 0.06 There are 292 ways to make $1.00 There are 2 ways to make $0.06 0 • Sigma series input: 3 output: 1 2 3 Shortest sequences from 1 to N such that each element is the sum of two previous elements. 4 1 2 4 87 1 2 4 8 16 24 28 29 58 87 99 1 2 4 8 16 32 33 66 99 -1 Useful C functions int atoi(char* s); converts C strings to ints atoi(“100”) == 100 double atof(char* s); converts C strings to doubles atoi(“100.0”) == 100.0 int strcasecomp(char* s1, char* s2); case-insensitive C string comparison strcasecmp(“aCm”,“ACm”) == 0 long strtol(char* s, NULL, int base) arbitrary conversion from a string in bases (2-36) to a long int strtol(“Charlie”, NULL, 36) == 2147483647L use man for more... sprintf int sprintf(char* str, char* format, ...); prints anything to the string str char str[100]; sprintf(str,“%d”,42); // str is “42” sprintf(str,“%f”,42.0); // str is “42.0” flexible formatting: sprintf(str,“%10d”,42); // str is “ 42” right/left justify: sprintf(str,“%-10d”,42); // str is “42 ” Two ACM programming skills A chance to “improve” your C/C++ … Preparation for the ACM competition ... Problem Insight and Execution ... 1 Get into the minds of the judges 2 Anxiety! Key Skill #1: mindreading Get into the minds of the judges 100% 0% “What cases should I handle?” spectrum Key Skill #2: Anxiety! anxiety Dynamic Programming Strategy: create a table of partial results & build on it. divis.cc T(n) = number of steps yet to go T(n) = T(3n+1) + 1 if n odd T(n) = T(n/2) + 1 if n even Dynamic Programming Keys: create a table of partial results, articulate what each table cell means, then build it up... i = possible remainder Table T 0 divis.cc j = items considered so far 0 1 2 3 4 5 6 1 1 6 2 -3 the list 1 2 4 the divisor 3 T[i][j] is 1 if i is a possible remainder using the first j items in the list. Dynamic programs can be short #include <cstdio> #include <iostream> #include <vector> vector<int> v(10000); vector<bool> m(100); // old mods vector<bool> m2(100); // new mods int n, k; int main() { cin >> n; // garbage while (cin >> n) { cin >> k; bool divisible() { fill(m.begin(),m.end(),false); m[0] = true; for (int i=0; i<n; i++) { cin >> v[i]; v[i] = abs(v[i]); v[i] %= k; } for (int i=0; i<n; i++) { cout << (divisible() ? "D" : "Not d") << "ivisible\n"; /* not giving away all of the code */ /* here the table is built (6 lines) */ } return m[0]; } cout << endl; } acknowledgment: Matt Brubeck } STL: http://www.sgi.com/Technology/STL General ACM Programming Try brute force first (or at least consider it) -- sometimes it will work fine… -- sometimes it will take a _bit_ too long -- sometimes it will take _way_ too long Best bugs from last week: getting the input in the “pea” problem: for (int j=1 ; j<N ; ++j) { cin >> Array[i]; } filling in the table in the “divis” problem: Table[i + n % k] = 1; Table[i - n % k] = 1; New Problem Word Chains Input A list of words hertz doze jazz aplomb hajj ceded zeroth dozen envy ballistic yearn Output yes or no -- can these words be chained together such that the last letter of one is the first letter of the next… ? Knapsack Problem Maximize loot w/ weight limit of 4. Number of objects considered w Weight available for use 0 1 2 3 n 4 V(n,w) = 1 2 object wt. val. 1 3 8 2 2 5 3 1 1 4 2 5 3 4 V(n,w) = max value stealable w/ ‘n’ objects & ‘w’ weight C Output printf, fprintf, sprintf(char* s, const char* format, …) the destination the format string the values possible format strings % -#0 .4 h d 12 minimum field width type size modifier precision flags start character 0 + (space) # d u o x f e g c s n % left-justify pad w/ zeros use sign (+ or -) use sign ( or -) deviant operation decimal integers unsigned (decimal) ints octal integers hexadecimal integers doubles (floats are cast) doubles (exp. notation) f or e, if exp < -3 or -4 character string outputs # of chars written !! two of these print a ‘%’ allowed size modifiers h l L short long (lowercase L) long double C Output value = 42 %10.4d %-#12x value = -42 0042 0x2a -0042 0xffffffd6 %+10.4g value = 42 +42 value = -42.419 -42.42 %- 10.4g 42 -42.42 %-#10.4g 42.00 -42.42 value = “forty-two” %10.5s forty