├── README.md ├── world_finals ├── latest.pdf ├── src │ ├── testing │ │ ├── prelude │ │ └── trycompile.sh │ ├── code │ │ ├── Misc │ │ │ ├── stack_size.cpp │ │ │ ├── Alphabeta.cpp │ │ │ ├── Segment tree.cpp │ │ │ ├── Longest ascending subsequence.cpp │ │ │ ├── Cubic equation solver.cpp │ │ │ ├── javaExample.java │ │ │ ├── C++ IO format │ │ │ ├── Equation solving.cpp │ │ │ ├── Common bugs │ │ │ ├── fft.cpp │ │ │ └── Calendar.cpp │ │ ├── NumberTheory │ │ │ ├── binomial.cpp │ │ │ ├── sum_divisors.cpp │ │ │ ├── euler_phi.cpp │ │ │ ├── Sieve of Eratosthenes.cpp │ │ │ ├── Discrete logarithm solver.cpp │ │ │ └── Chinese remaindering and ext. Euclidean.cpp │ │ ├── Geometry │ │ │ ├── Is Left Of.cpp │ │ │ ├── Basics.cpp │ │ │ ├── Heron's formula for triangle area.cpp │ │ │ ├── Line-line intersection.cpp │ │ │ ├── Rectangle in rectangle test.cpp │ │ │ ├── Area of intersection of two circles.cpp │ │ │ ├── Circle described by three points.cpp │ │ │ ├── Circle described by two points and one line.cpp │ │ │ ├── Centroid and area of a simple polygon.cpp │ │ │ ├── Line-circle intersection.cpp │ │ │ ├── Point in polygon.cpp │ │ │ ├── Points of intersection of two circles.cpp │ │ │ ├── Convex-hull.cpp │ │ │ ├── Segment-segment intersection.cpp │ │ │ ├── Circle described by two lines and one point.cpp │ │ │ └── Parabola-line intersection.cpp │ │ ├── Combinatorics │ │ │ ├── Josephus Ring Survivor.cpp │ │ │ ├── derangement.cpp │ │ │ ├── Digit occurrence count.cpp │ │ │ ├── (Un)Ranking of K-permutation out of N.cpp │ │ │ └── (Un)Ranking of K-combination out of N.cpp │ │ ├── String │ │ │ ├── KMP string matching.cpp │ │ │ ├── Manacher's algorithm.cpp │ │ │ └── trie.cpp │ │ └── Graph │ │ │ ├── Dijkstra.cpp │ │ │ ├── mst.cpp │ │ │ ├── Steiner.cpp │ │ │ ├── bellmanford_negativecycle_path.cpp │ │ │ ├── Cut edges and 2-edge-connected components.cpp │ │ │ ├── 2-Sat and strongly connected component.cpp │ │ │ ├── Min cost max flow.cpp │ │ │ ├── Cut vertices and 2-connected components.cpp │ │ │ ├── Fast flow.cpp │ │ │ └── Bipartite weighted matching.cpp │ └── Makefile ├── UofC_Notebook_2004.pdf ├── 2005_World_Finals_Archive.pdf ├── 2006_World_Finals_Archive.pdf ├── 2007_World_Finals_Archive.pdf ├── 2008_World_Finals_Archive.pdf ├── 2012_World_Finals_Archive.pdf └── 2017_World_Finals_Archive.pdf ├── misc ├── keymap.txt ├── strrev.c ├── bitcount.c ├── roman.cc └── sqr_index.c ├── graph ├── edmondskarp │ └── test.cpp ├── toposort │ ├── test.cpp │ └── toposort.cpp ├── dijkstra │ ├── test.cpp │ ├── dijkstra_min.cpp │ └── dijkstra.cpp ├── kruskal │ ├── test.cpp │ └── kruskal.cpp ├── bellmanford │ ├── test.cpp │ └── bellmanford.cpp ├── graph.cpp ├── top_sort.cc ├── floyd.c ├── bellmanford.c ├── min_span_tree2.c └── strong_conn.cc ├── data_structures ├── disjoint │ ├── test.cpp │ └── disjoint.cpp ├── heap │ ├── test.cpp │ └── heap.cpp ├── fenwick_tree.cpp └── unionfind.c ├── num_theory ├── gcd.cpp ├── num_divisors.c ├── sum_divisors.c ├── eulerphi.c ├── isprime.c ├── farey.cc ├── extended_euclid.cpp ├── isprime_fast.cpp ├── factinfact.c ├── modular_inverse.cpp ├── primefactor.c └── primes.c ├── arithmetic ├── fast_exp_mod.c ├── fast_exp.c ├── solve_quad.c ├── simpsons.c ├── solve_cubic.c ├── discrete_log.cc └── t_func.c ├── 2d_geometry ├── dist_2d.c ├── area_regpoly.c ├── area_ellipse.c ├── soddy_circ_radius.c ├── closest_pt_iline.c ├── area_triangle.cpp ├── dist_iline.c ├── reflect.c ├── angle_2d180.cc ├── angle_2d.c ├── circ_tangents.c ├── area_heron.c ├── closest_pt_lineseg.c ├── rotate_2d.c ├── midpts2vert.c ├── isect_circ_area.c ├── centroid.c ├── pts2_genline.c ├── circ_3pts.c ├── pt_in_poly.c ├── isect_iline.c ├── point_in_convex_poly.c ├── pt_leftright.c ├── ccw.c ├── area_poly.cpp ├── lat_poly_pick.c ├── isect_circ_test.c └── area_unionrect.c ├── generators ├── catalan.c ├── nqueens.c ├── pyth.c └── gen_bin_card.c ├── combinatorics ├── permdex_distinct.c ├── factorial_dig.c ├── josephus.c ├── binomial.c ├── digit_count.c └── necklace.c ├── 3d_geometry ├── greatcircle.c └── area_cpoly3d.c ├── Search ├── queen.c ├── walk.c ├── color.c ├── golden.c └── binsearch.c ├── dynamic ├── integer_partition.c ├── asc_subseq2.c └── long_common_subseq.c ├── c++ ├── string_tokenizer.cc └── pqueue.cc ├── Parsing └── infix_to_postfix.c └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | # Code-Archive 2 | -------------------------------------------------------------------------------- /world_finals/latest.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UAPSPC/Code-Archive/HEAD/world_finals/latest.pdf -------------------------------------------------------------------------------- /world_finals/src/testing/prelude: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { } 4 | -------------------------------------------------------------------------------- /world_finals/UofC_Notebook_2004.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UAPSPC/Code-Archive/HEAD/world_finals/UofC_Notebook_2004.pdf -------------------------------------------------------------------------------- /world_finals/2005_World_Finals_Archive.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UAPSPC/Code-Archive/HEAD/world_finals/2005_World_Finals_Archive.pdf -------------------------------------------------------------------------------- /world_finals/2006_World_Finals_Archive.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UAPSPC/Code-Archive/HEAD/world_finals/2006_World_Finals_Archive.pdf -------------------------------------------------------------------------------- /world_finals/2007_World_Finals_Archive.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UAPSPC/Code-Archive/HEAD/world_finals/2007_World_Finals_Archive.pdf -------------------------------------------------------------------------------- /world_finals/2008_World_Finals_Archive.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UAPSPC/Code-Archive/HEAD/world_finals/2008_World_Finals_Archive.pdf -------------------------------------------------------------------------------- /world_finals/2012_World_Finals_Archive.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UAPSPC/Code-Archive/HEAD/world_finals/2012_World_Finals_Archive.pdf -------------------------------------------------------------------------------- /world_finals/2017_World_Finals_Archive.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UAPSPC/Code-Archive/HEAD/world_finals/2017_World_Finals_Archive.pdf -------------------------------------------------------------------------------- /world_finals/src/code/Misc/stack_size.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | void remove_stack_size_limit() { 3 | struct rlimit rl; 4 | getrlimit(RLIMIT_STACK, &rl); 5 | rl.rlim_cur = RLIM_INFINITY; 6 | setrlimit(RLIMIT_STACK, &rl); 7 | } 8 | -------------------------------------------------------------------------------- /world_finals/src/Makefile: -------------------------------------------------------------------------------- 1 | archive.pdf : archive.tex 2 | pdflatex -shell-escape archive 3 | mv archive.pdf ../latest.pdf 4 | 5 | test: 6 | cd testing; find ../code -name "*.cpp" -exec ./trycompile.sh "{}" \; 7 | 8 | format: 9 | clang-format -style=file -i code/*/*.cpp 10 | -------------------------------------------------------------------------------- /world_finals/src/code/NumberTheory/binomial.cpp: -------------------------------------------------------------------------------- 1 | // binomial coefficient C(n,k) 2 | long long Cdp[51][51]; // memset to -1 3 | long long C(int n, int k) { 4 | if(Cdp[n][k] != -1) return Cdp[n][k]; 5 | return Cdp[n][k] = (k == 0 || k == n ? 1 : C(n - 1, k - 1) + C(n - 1, k)); 6 | } 7 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Is Left Of.cpp: -------------------------------------------------------------------------------- 1 | #include "Basics.cpp" 2 | // Is z to left of line a-b? 3 | bool IsLeftOf(point a, point b, point z, bool includeStraight) { 4 | double res = cross(b - a, z - a); 5 | if(includeStraight && res > -eps) 6 | return true; 7 | else 8 | return res > eps; 9 | } -------------------------------------------------------------------------------- /world_finals/src/code/Combinatorics/Josephus Ring Survivor.cpp: -------------------------------------------------------------------------------- 1 | /* Josephus Ring Survivor (n people, dismiss every m’th) */ 2 | const int MaxN = 1000; 3 | int survive[MaxN]; 4 | void josephus(int n, int m) { 5 | survive[1] = 0; 6 | for(int i = 2; i <= n; i++) survive[i] = (survive[i - 1] + (m % i)) % i; 7 | } 8 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Basics.cpp: -------------------------------------------------------------------------------- 1 | double eps = 1e-6; 2 | typedef complex point; 3 | struct circle { 4 | point c; 5 | double r; 6 | circle(point c = {}, double r = 0): c(c), r(r) {} 7 | }; 8 | double cross(point a, point b) { return imag(conj(a) * b); } 9 | double dot(point a, point b) { return real(conj(a) * b); } 10 | -------------------------------------------------------------------------------- /misc/keymap.txt: -------------------------------------------------------------------------------- 1 | remove Lock = Caps_Lock 2 | remove Control = Control_L 3 | keysym Control_L = Caps_Lock 4 | keysym Caps_Lock = Control_L 5 | add Lock = Caps_Lock 6 | add Control = Control_L 7 | keycode 22 = Escape 8 | keycode 36 = grave asciitilde 9 | keycode 49 = BackSpace 10 | keycode 50 = backslash bar brokenbar 11 | keycode 95 = BackSpace 12 | 13 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Heron's formula for triangle area.cpp: -------------------------------------------------------------------------------- 1 | // Given side lengths a, b, c, returns area or -1 if triangle is 2 | // impossible 3 | double area_heron(double a, double b, double c) { 4 | if(a < b) swap(a, b); 5 | if(a < c) swap(a, c); 6 | if(b < c) swap(b, c); 7 | if(a > b + c) return -1; 8 | return sqrt((a + b + c) * (c - a + b) * (c + a - b) * (a + b - c) / 16.0); 9 | } 10 | -------------------------------------------------------------------------------- /graph/edmondskarp/test.cpp: -------------------------------------------------------------------------------- 1 | #include "EdmondsKarp.cpp" 2 | 3 | // Test flow implementation. 4 | int main(int argc, char **argv) 5 | { 6 | FlowGraph FG(7); 7 | FG.addEdge(0,1,3); 8 | FG.addEdge(0,2,5); 9 | FG.addEdge(1,2,4); 10 | FG.addEdge(2,4,6); 11 | FG.addEdge(2,5,3); 12 | FG.addEdge(4,5,1); 13 | FG.addEdge(4,3,3); 14 | FG.addEdge(3,6,10); 15 | FG.addEdge(5,6,4); 16 | cout << EdmondsKarp(FG, 0, 6) << endl; 17 | } -------------------------------------------------------------------------------- /world_finals/src/testing/trycompile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # https://icpc.baylor.edu/worldfinals/programming-environment 4 | 5 | set -e 6 | rm -f *.cpp 7 | NAME=`basename "$1"` 8 | DIR=`dirname "$1"` 9 | cat prelude > "$NAME" 10 | cat "$1" >> "$NAME" 11 | echo "$1 ... " 12 | sleep 0.01 13 | g++ -I "$DIR" -g -O2 -std=gnu++14 -static "$NAME" -o gentest 14 | ./gentest 15 | rm "$NAME" gentest 16 | echo -e "\e[92mOK!\e[39m" 17 | echo 18 | -------------------------------------------------------------------------------- /world_finals/src/code/NumberTheory/sum_divisors.cpp: -------------------------------------------------------------------------------- 1 | // Returns the sum of all positive divisors for a positive integer N 2 | // WARNING: check if usage of `pow` is ok. 3 | long long sum_divisors(long long n) { 4 | long long res = 1; 5 | for(int i = 2; i*i <= n; i++) { 6 | int count = 0; 7 | for(; n % i == 0; count++) n /= i; 8 | if(count) res *= (pow(i, count+1)-1)/(i-1); 9 | } 10 | if(n > 1) res *= (pow(n, 2)-1)/(n-1); 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /world_finals/src/code/NumberTheory/euler_phi.cpp: -------------------------------------------------------------------------------- 1 | // Returns the number of positive integers less than N that are 2 | // relatively prime to N. WARNING: check if usage of `pow` is ok. 3 | long long phi(long long n) { 4 | long long res = 1; 5 | for(int i = 2; i * i <= n; i++) { 6 | int count = 0; 7 | for(; n % i == 0; count++) n /= i; 8 | if(count) res *= pow(i, count) - pow(i, count - 1); 9 | } 10 | if(n > 1) res *= n - 1; 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Line-line intersection.cpp: -------------------------------------------------------------------------------- 1 | #include "Basics.cpp" 2 | // Intersects point of lines a-b and c-d 3 | // -1->coincide,0->parallel,1->intersected(inter. point in 'p') 4 | int line_line_inter(point a, point b, point c, point d, point &p) { 5 | if(abs(cross(b - a, d - c)) > eps) { 6 | p = cross(c - a, d - c) / cross(b - a, d - c) * (b - a) + a; 7 | return 1; 8 | } 9 | if(abs(cross(b - a, b - c)) > eps) return 0; 10 | return -1; 11 | } 12 | -------------------------------------------------------------------------------- /world_finals/src/code/NumberTheory/Sieve of Eratosthenes.cpp: -------------------------------------------------------------------------------- 1 | // Returns all prime numbers in [0,n] 2 | const int maxn = 1000000; 3 | int isnprime[maxn]; 4 | vector sieve(int n) { 5 | memset(isnprime, 0, sizeof isnprime); 6 | isnprime[0] = isnprime[1] = 1; 7 | vector ps; 8 | for(int i = 2; i < n; i++) 9 | if(!isnprime[i]) { 10 | ps.push_back(i); 11 | if(n / i >= i) 12 | for(int j = i * i; j <= n; j += i) isnprime[j] = 1; 13 | } 14 | return ps; 15 | } 16 | -------------------------------------------------------------------------------- /graph/toposort/test.cpp: -------------------------------------------------------------------------------- 1 | #include "toposort.cpp" 2 | 3 | #include 4 | 5 | // Topological sort example. 6 | int main(int argc, char **argv) 7 | { 8 | Graph G(9); 9 | G.addEdge(0, 1); 10 | G.addEdge(1, 4); 11 | G.addEdge(1, 5); 12 | G.addEdge(2, 4); 13 | G.addEdge(3, 5); 14 | G.addEdge(3, 8); 15 | G.addEdge(4, 6); 16 | G.addEdge(4, 7); 17 | G.addEdge(5, 7); 18 | vector sorted = Toposort(G); 19 | for (int i = 0; i < sorted.size(); ++i) 20 | cout << sorted[i] << ' '; 21 | cout << endl; 22 | } 23 | -------------------------------------------------------------------------------- /graph/dijkstra/test.cpp: -------------------------------------------------------------------------------- 1 | #include "dijkstra_min.cpp" 2 | 3 | #include 4 | 5 | // Test of Djikstra's algorithm. 6 | int main(int argc, char **argv) 7 | { 8 | Graph G(6); 9 | G.addEdge(0, 1, 12); 10 | G.addEdge(0, 2, 3); 11 | G.addEdge(2, 3, 1); 12 | G.addEdge(3, 1, 2); 13 | G.addEdge(3, 4, 7); 14 | G.addEdge(1, 5, 1); 15 | G.addEdge(5, 4, 1); 16 | vector prev = Dijkstra(G, 0); 17 | cout << "Node\tPrev" << endl; 18 | for (int i = 0; i < prev.size(); ++i) 19 | cout << i << '\t' << prev[i] << endl; 20 | } 21 | -------------------------------------------------------------------------------- /graph/kruskal/test.cpp: -------------------------------------------------------------------------------- 1 | #include "kruskal.cpp" 2 | 3 | #include 4 | 5 | // Test Kruskal's MST algorithm. 6 | int main(int argc, char **argv) 7 | { 8 | Graph G; 9 | G.AddBiEdge(0,1,1); 10 | G.AddBiEdge(1,2,10); 11 | G.AddBiEdge(2,3,3); 12 | G.AddBiEdge(2,5,1); 13 | G.AddBiEdge(3,4,1); 14 | G.AddBiEdge(5,4,1); 15 | vector MST = KruskalMST(G); 16 | for (int i = 0; i < MST.size(); ++i) { 17 | cout << MST[i].first.a << " -> " << MST[i].first.b << " (" << MST[i].second << ")" << endl; 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Rectangle in rectangle test.cpp: -------------------------------------------------------------------------------- 1 | // Can rectangle with dims x*y fit inside box with dims w*h? 2 | // Returns true for a "tight fit", if false is desired then swap 3 | // strictness of inequalities. 4 | bool rect_in_rect(double x, double y, double w, double h) { 5 | if(x > y) swap(x, y); 6 | if(w > h) swap(w, h); 7 | if(w < x) return false; 8 | if(y <= h) return true; 9 | double a = y * y - x * x; 10 | double b = x * h - y * w; 11 | double c = x * w - y * h; 12 | return a * a <= b * b + c * c; 13 | } 14 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Area of intersection of two circles.cpp: -------------------------------------------------------------------------------- 1 | #include "Basics.cpp" 2 | double circ_inter_area(circle &a, circle &b) { 3 | double d = abs(b.c - a.c); 4 | if(d <= b.r - a.r) return a.r * a.r * M_PI; 5 | if(d <= a.r - b.r) return b.r * b.r * M_PI; 6 | if(d >= a.r + b.r) return 0; 7 | double alpha = acos((a.r * a.r + d * d - b.r * b.r) / (2 * a.r * d)); 8 | double beta = acos((b.r * b.r + d * d - a.r * a.r) / (2 * b.r * d)); 9 | return a.r * a.r * (alpha - 0.5 * sin(2 * alpha)) + b.r * b.r * (beta - 0.5 * sin(2 * beta)); 10 | } 11 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Circle described by three points.cpp: -------------------------------------------------------------------------------- 1 | #include "Basics.cpp" 2 | // Returns whether they form a circle or not. 3 | // 'center' and 'r' contain the circle if there is one 4 | bool get_circle(point p1, point p2, point p3, point ¢er, double &r) { 5 | double g = 2 * imag(conj(p2 - p1) * (p3 - p2)); 6 | if(abs(g) < eps) return false; 7 | center = p1 * (norm(p3) - norm(p2)); 8 | center += p2 * (norm(p1) - norm(p3)); 9 | center += p3 * (norm(p2) - norm(p1)); 10 | center /= point(0, g); 11 | r = abs(p1 - center); 12 | return true; 13 | } 14 | -------------------------------------------------------------------------------- /world_finals/src/code/Combinatorics/derangement.cpp: -------------------------------------------------------------------------------- 1 | // combinatorial: derangement 2 | // count the number of permutations of n elements, such that no 3 | // element appears in its original position math formula: 4 | // derange(n)=ceil(factorial(n)/e+0.5), probability of 5 | // derange(n)/factorial(n) converges to 0.36787944 6 | const int maxN = 21; 7 | long long derange[maxN]; 8 | long long cal_derange(int n) { 9 | derange[0] = 1; 10 | derange[1] = 0; 11 | for(int i = 2; i <= n; i++) derange[i] = (i - 1) * (derange[i - 1] + derange[i - 2]); 12 | return derange[n]; 13 | } 14 | -------------------------------------------------------------------------------- /world_finals/src/code/Misc/Alphabeta.cpp: -------------------------------------------------------------------------------- 1 | int inf = 1e9; 2 | struct state { 3 | int score() { return 0; } // TODO 4 | vector children() { return {}; } // TODO 5 | }; 6 | int ab(state s, int alpha = -inf, int beta = inf, int player = 1) { 7 | auto ch = s.children(); 8 | if(ch.size() == 0) return s.score() * player; // if terminal 9 | int value = -inf; 10 | for(state c: ch) { // try best moves first! 11 | value = max(value, -ab(c, -beta, -alpha, -player)); 12 | alpha = max(alpha, value); 13 | if(alpha >= beta) break; 14 | } 15 | return value; 16 | } 17 | -------------------------------------------------------------------------------- /world_finals/src/code/Combinatorics/Digit occurrence count.cpp: -------------------------------------------------------------------------------- 1 | // Given digit d and value N, returns # of times d occurs from 1..N 2 | long long digit_count(int digit, int N) { 3 | long long res = 0; 4 | char buff[15]; 5 | int i, count; 6 | if(N <= 0) return 0; 7 | res += N / 10 + ((N % 10) >= digit ? 1 : 0); 8 | if(digit == 0) res--; 9 | res += digit_count(digit, N / 10 - 1) * 10; 10 | sprintf(buff, "%d", N / 10); 11 | for(i = 0, count = 0; i < strlen(buff); i++) 12 | if(buff[i] == digit + '0') count++; 13 | res += (1 + N % 10) * count; 14 | return res; 15 | } 16 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Circle described by two points and one line.cpp: -------------------------------------------------------------------------------- 1 | #include "Parabola-line intersection.cpp" 2 | // Returns number of circles that pass through point a and b and 3 | // are tangent to the line c-d 4 | // 'ans' has all possible circles with radius > 0 5 | int get_circle(point a, point b, point c, point d, vector &ans) { 6 | point pa = (a + b) / 2.0; 7 | point pb = (b - a) * point(0, 1) + pa; 8 | vector ta; 9 | parabola_line_inter(a, c, d, pa, pb, ta); 10 | for(point p: ta) ans.push_back(circle(p, abs(a - p))); 11 | return ans.size(); 12 | } 13 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Centroid and area of a simple polygon.cpp: -------------------------------------------------------------------------------- 1 | #include "Basics.cpp" 2 | // Points must be oriented (CW or CCW), and non-convex is OK 3 | // Returns (nan,nan) if area of polygon is zero 4 | point centroid(vector p) { 5 | int n = p.size(); // should be at least 1 6 | double area = 0; 7 | point c(0, 0); // Not required for area of polygon 8 | for(int i = n - 1, j = 0; j < n; i = j++) { 9 | double a = cross(p[i], p[j]) / 2; 10 | area += a; 11 | c += (p[i] + p[j]) * (a / 3); 12 | } 13 | c /= area; 14 | return c; // or return 'area' for the area of polygon 15 | } 16 | -------------------------------------------------------------------------------- /graph/bellmanford/test.cpp: -------------------------------------------------------------------------------- 1 | #include "bellmanford.cpp" 2 | 3 | #include 4 | 5 | int main(int argc, char **argv) 6 | { 7 | // Simple graph for testing purposes. 8 | Graph G; 9 | G.AddEdge(0, 1, 1); 10 | G.AddEdge(1, 2, 1); 11 | G.AddEdge(2, 3, 1); 12 | G.AddEdge(3, 0, -3); 13 | // Run Bellman Ford SSSP algorithm. 14 | vector dists = BellmanFord(G, 0); 15 | // Report SSSP distances. 16 | for (int i = 0;i < dists.size(); ++i) 17 | cout << i << '\t' << dists[i] << endl; 18 | // Check for negative cycle. 19 | cout << "Negative cycle:\t" << HasNegativeCycle(G, dists) << endl; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Line-circle intersection.cpp: -------------------------------------------------------------------------------- 1 | #include "Basics.cpp" 2 | // Intersects (infinite) line a-b with circle c 3 | // Intersection points are in 'inter' 4 | // 0 -> no intersection, 1 -> tangent, 2 -> two intersections 5 | int line_circ_inter(point a, point b, circle c, vector &inter) { 6 | c.c -= a; 7 | b -= a; 8 | point m = b * real(c.c / b); 9 | double d2 = norm(m - c.c); 10 | if(d2 > c.r * c.r) return 0; 11 | double l = sqrt((c.r * c.r - d2) / norm(b)); 12 | inter.push_back(a + m + l * b); 13 | if(abs(l) > eps) inter.push_back(a + m - l * b); 14 | return inter.size(); 15 | } 16 | -------------------------------------------------------------------------------- /world_finals/src/code/Misc/Segment tree.cpp: -------------------------------------------------------------------------------- 1 | const int maxn = 1 << 20; // must be a power of 2 2 | long long seg[2 * maxn]; 3 | // Add the value 'val' to the index 'num' 4 | void add(int num, long long val) { 5 | num += maxn; 6 | while(num > 0) { 7 | seg[num] += val; 8 | num >>= 1; 9 | } 10 | } 11 | // returns sum of the elements in range [0,num] 12 | long long get(int num) { 13 | num += maxn; 14 | long long ans = 0; 15 | ans = seg[num]; // Comment this to change the range to [0,num) 16 | while(num > 0) { 17 | if(num & 1) { ans += seg[num & (~1)]; } 18 | num >>= 1; 19 | } 20 | return ans; 21 | } 22 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Point in polygon.cpp: -------------------------------------------------------------------------------- 1 | #include "Basics.cpp" 2 | // outside -> 0, inside -> 1, on the border -> 2 3 | int pt_in_poly(vector &p, point &a) { 4 | int n = p.size(); 5 | int inside = false; 6 | for(int i = 0, j = n - 1; i < n; j = i++) { 7 | if(abs(cross(a - p[i], a - p[j])) < eps && dot(a - p[i], a - p[j]) < eps) return 2; 8 | if((imag(p[i]) <= imag(a) && imag(a) < imag(p[j])) || (imag(p[j]) <= imag(a) && imag(a) < imag(p[i]))) 9 | if(real(a) - real(p[i]) < (real(p[j]) - real(p[i])) * (imag(a) - imag(p[i])) / (imag(p[j]) - imag(p[i]))) inside = !inside; 10 | } 11 | return inside; 12 | } 13 | -------------------------------------------------------------------------------- /data_structures/disjoint/test.cpp: -------------------------------------------------------------------------------- 1 | #include "disjoint.cpp" 2 | 3 | #include 4 | 5 | // Demonstration of Disjoint Set data structure. 6 | int main(int argc, char **argv) 7 | { 8 | // Create 5 disjoint elements. 9 | DisjointSets DS(5); 10 | for (int i = 0; i < 5; ++i) DS.MakeSet(i); 11 | // Union together subsets. 12 | DS.Union(0,1); 13 | DS.Union(1,2); 14 | DS.Union(3,4); 15 | // Query subsets. 16 | cout << DS.Find(0) << ' ' << DS.Find(2) << endl; 17 | cout << DS.Find(4) << endl; 18 | // This union should result in all elements belonging to the same set. 19 | DS.Union(4,0); 20 | cout << DS.Find(0) << ' ' << DS.Find(1) << ' ' << DS.Find(4) << endl; 21 | } 22 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Points of intersection of two circles.cpp: -------------------------------------------------------------------------------- 1 | #include "Basics.cpp" 2 | // Intersects two circles and intersection points are in 'inter' 3 | // -1-> outside, 0-> inside, 1-> tangent, 2-> 2 intersections 4 | int circ_circ_inter(circle &a, circle &b, vector &inter) { 5 | double d2 = norm(b.c - a.c), rS = a.r + b.r, rD = a.r - b.r; 6 | if(d2 > rS * rS) return -1; 7 | if(d2 < rD * rD) return 0; 8 | double ca = 0.5 * (1 + rS * rD / d2); 9 | point z = point(ca, sqrt(a.r * a.r / d2 - ca * ca)); 10 | inter.push_back(a.c + (b.c - a.c) * z); 11 | if(abs(z.imag()) > eps) inter.push_back(a.c + (b.c - a.c) * conj(z)); 12 | return inter.size(); 13 | } 14 | -------------------------------------------------------------------------------- /num_theory/gcd.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Greatest common divisor of two nonnegative integers. 3 | 4 | Author: Zac Friggstad 5 | 6 | For nonnegative integers a,b, gcd(a,b) is the largest integer 7 | that divides both a and b. By convension gcd(0,0) = 0. 8 | 9 | Two different implementations are present here. Both work just fine. 10 | 11 | Running time of both: O(log(a) + log(b)) 12 | 13 | Reliability: UVA 11417 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | int gcd(int a, int b) { return b ? gcd(b, a%b) : a; } 21 | 22 | int gcd_iterative(int a, int b) { 23 | while (b) { 24 | a %= b; 25 | swap(a, b); 26 | } 27 | return a; 28 | } 29 | -------------------------------------------------------------------------------- /arithmetic/fast_exp_mod.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Fast Exponentiation mod m 3 | * 4 | * Author: Howard Cheng 5 | * 6 | * Given b, n, and m, computes b^n mod m quickly. 7 | * 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | int fast_exp(int b, int n, int m) 14 | { 15 | int res = 1; 16 | int x = b; 17 | 18 | while (n > 0) { 19 | if (n & 0x01) { 20 | n--; 21 | res = (res * x) % m; 22 | } else { 23 | n >>= 1; 24 | x = (x * x) % m; 25 | } 26 | } 27 | 28 | return res; 29 | } 30 | 31 | int main(void) 32 | { 33 | int b, n, m; 34 | 35 | while (scanf("%d %d %d", &b, &n, &m) == 3) { 36 | printf("%d^%d mod %d = %d\n", b, n, m, fast_exp(b, n, m)); 37 | } 38 | return 0; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /world_finals/src/code/NumberTheory/Discrete logarithm solver.cpp: -------------------------------------------------------------------------------- 1 | // Given prime P, B>0, and N, finds least L 2 | // such that B^L==N (mod P) 3 | // Returns -1, if no such L exist. 4 | map mow; 5 | int times(int a, int b, int m) { return (long long)a * b % m; } 6 | int power(int val, int power, int m) { 7 | int res = 1; 8 | for(int p = power; p; p >>= 1) { 9 | if(p & 1) res = times(res, val, m); 10 | val = times(val, val, m); 11 | } 12 | return res; 13 | } 14 | int discrete_log(int p, int b, int n) { 15 | int jump = sqrt(double(p)); 16 | mow.clear(); 17 | for(int i = 0; i < jump && i < p - 1; ++i) mow[power(b, i, p)] = i + 1; 18 | for(int i = 0, j; i < p - 1; i += jump) 19 | if(j = mow[times(n, power(b, p - 1 - i, p), p)]) return (i + j - 1) % (p - 1); 20 | return -1; 21 | } 22 | -------------------------------------------------------------------------------- /world_finals/src/code/String/KMP string matching.cpp: -------------------------------------------------------------------------------- 1 | // Given strings t and p, return the indices of t where p occurs 2 | // as a substring 3 | vector compute_prefix(string s) { 4 | vector pi(s.size(), -1); 5 | int k = -1; 6 | for(int i = 1; i < s.size(); i++) { 7 | while(k >= 0 && s[k + 1] != s[i]) k = pi[k]; 8 | if(s[k + 1] == s[i]) k++; 9 | pi[i] = k; 10 | } 11 | return pi; 12 | } 13 | vector kmp_match(string t, string p) { 14 | vector pi = compute_prefix(p); 15 | vector shifts; 16 | int m = -1; 17 | for(int i = 0; i < t.size(); i++) { 18 | while(m > -1 && p[m + 1] != t[i]) m = pi[m]; 19 | if(p[m + 1] == t[i]) m++; 20 | if(m == p.size() - 1) { 21 | shifts.push_back(i + 1 - p.size()); 22 | m = pi[m]; 23 | } 24 | } 25 | return shifts; 26 | } 27 | -------------------------------------------------------------------------------- /world_finals/src/code/String/Manacher's algorithm.cpp: -------------------------------------------------------------------------------- 1 | // Returns half of length of largest palindrome centered at 2 | // every position in the string 3 | // Add \0 at start, end, and middle to handle palindromes between 4 | // characters + get length of largest palindrome at each index. 5 | // Then, int characterBefore = i / 2; int lenToStart = P[i] / 2; 6 | // int lenToEnd = lenToStart - (i % 2 == 0); 7 | vector manacher(string s) { 8 | vector ans(s.size(), 0); 9 | int maxi = 0; 10 | for(int i = 1; i < s.size(); i++) { 11 | int k = 0; 12 | if(maxi + ans[maxi] >= i) k = min(ans[maxi] + maxi - i, ans[2 * maxi - i]); 13 | for(; s[i + k] == s[i - k] && i - k >= 0 && i + k < s.size(); k++) 14 | ; 15 | ans[i] = k - 1; 16 | if(i + ans[i] > maxi + ans[maxi]) maxi = i; 17 | } 18 | return ans; 19 | } 20 | -------------------------------------------------------------------------------- /world_finals/src/code/Misc/Longest ascending subsequence.cpp: -------------------------------------------------------------------------------- 1 | typedef pair pii; 2 | int comp(const pii &a, const pii &b) { 3 | if(a.first != b.first) return a.first < b.first; 4 | return a.second < b.second; // return 0 to find strictly ascending subsequence 5 | } 6 | vector lis(const vector &in) { 7 | vector l; 8 | vector par(in.size(), -1); 9 | for(int i = 0; i < in.size(); i++) { 10 | int ind = lower_bound(l.begin(), l.end(), pii(in[i], i), comp) - l.begin(); 11 | if(ind == l.size()) l.push_back(pii(0, 0)); 12 | l[ind] = pii(in[i], i); 13 | if(ind != 0) par[i] = l[ind - 1].second; 14 | } 15 | vector ans; 16 | int ind = l.back().second; 17 | while(ind != -1) { 18 | ans.push_back(in[ind]); 19 | ind = par[ind]; 20 | } 21 | reverse(ans.begin(), ans.end()); 22 | return ans; 23 | } 24 | -------------------------------------------------------------------------------- /data_structures/heap/test.cpp: -------------------------------------------------------------------------------- 1 | #include "heap.cpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | // Example usage of heap datatype 8 | int main(int argc, char **argv) 9 | { 10 | Heap H; // Heap of int 11 | srand(time(NULL)); 12 | 13 | // Populate heap by inserting numbers one at a time. 14 | for (int i = 0; i < 20; ++i) H.Insert(rand()); 15 | // Pop elements in sorted order. 16 | while (H.Size() > 0) { 17 | cout << H.Top() << endl; 18 | H.Pop(); 19 | } 20 | 21 | cout << endl; 22 | 23 | // Populate heap by running "heapify" on vector. 24 | // O(N) 25 | vector toHeap; 26 | for (int i = 0; i < 20; ++i) toHeap.push_back(rand()); 27 | H.Heapify(toHeap); 28 | // Pop elements in sorted order. 29 | while (H.Size() > 0) { 30 | cout << H.Top() << endl; 31 | H.Pop(); 32 | } 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /world_finals/src/code/Graph/Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | const int maxn = 1000; // Max # of vertices 2 | int n; //# of vertices 3 | vector> v[maxn]; // weighted adjacency list 4 | int d[maxn]; // distance from source 5 | struct comp { 6 | bool operator()(int a, int b) { return (d[a] != d[b]) ? d[a] < d[b] : a < b; } 7 | }; 8 | set mark; 9 | void dijkstra(int source) { 10 | memset(d, -1, sizeof d); 11 | d[source] = 0; 12 | mark.clear(); 13 | for(int i = 0; i < n; ++i) mark.insert(i); 14 | while(mark.size()) { 15 | int x = *mark.rbegin(); 16 | mark.erase(x); 17 | if(d[x] == -1) break; 18 | for(auto &it: v[x]) { 19 | if(d[it.first] == -1 || d[x] + it.second < d[it.first]) { 20 | mark.erase(it.first); 21 | d[it.first] = d[x] + it.second; 22 | mark.insert(it.first); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /data_structures/disjoint/disjoint.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // Union-Find Algorithm with Union by Rank and Path Compression 6 | class DisjointSets { 7 | public: 8 | DisjointSets(int N) : parent(vector(N)), rank(vector(N)) {} 9 | void MakeSet(int i) { parent[i] = i; rank[i] = 0; } 10 | void Union(int i, int j) 11 | { 12 | int iRoot = Find(i); 13 | int jRoot = Find(j); 14 | if (iRoot == jRoot) return; 15 | if (rank[iRoot] < rank[jRoot]) parent[iRoot] = jRoot; 16 | else if (rank[iRoot] > rank[jRoot]) parent[jRoot] = iRoot; 17 | else { 18 | parent[jRoot] = iRoot; 19 | rank[iRoot] += 1; 20 | } 21 | } 22 | int Find(int i) 23 | { 24 | if (parent[i] != i) parent[i] = Find(parent[i]); 25 | return parent[i]; 26 | } 27 | private: 28 | vector parent; 29 | vector rank; 30 | }; 31 | -------------------------------------------------------------------------------- /world_finals/src/code/Misc/Cubic equation solver.cpp: -------------------------------------------------------------------------------- 1 | // Solves ax^3 + bx^2 + cx + d = 0 2 | vector solve_cubic(double a, double b, double c, double d) { 3 | long double a1 = b / a, a2 = c / a, a3 = d / a; 4 | long double q = (a1 * a1 - 3 * a2) / 9.0, sq = -2 * sqrt(q); 5 | long double r = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) / 54.0; 6 | double z = r * r - q * q * q, theta; 7 | vector res; 8 | res.clear(); 9 | if(z <= 0) { 10 | theta = acos(r / sqrt(q * q * q)); 11 | res.push_back(sq * cos(theta / 3.0) - a1 / 3.0); 12 | res.push_back(sq * cos((theta + 2.0 * M_PI) / 3.0) - a1 / 3.0); 13 | res.push_back(sq * cos((theta + 4.0 * M_PI) / 3.0) - a1 / 3.0); 14 | return res; 15 | } 16 | double v = pow(sqrt(z) + fabs(r), 1 / 3.0); 17 | v += q / v; 18 | v *= (r < 0) ? 1 : -1; 19 | v -= a1 / 3.0; 20 | res.push_back(v); 21 | return res; 22 | } 23 | -------------------------------------------------------------------------------- /graph/bellmanford/bellmanford.cpp: -------------------------------------------------------------------------------- 1 | #include "../graph.cpp" 2 | 3 | // Bellman-Ford algorithm. Update distances N-1 times, where N is the number of nodes in the graph. 4 | vector BellmanFord(const Graph& G, int source) 5 | { 6 | vector dist(G.NumNodes(), numeric_limits::max()); 7 | dist[source] = 0; 8 | for (int i = 0; i < G.NumNodes()-1; ++i) 9 | for (ConstEdgeIterator it = G.edges.begin(); it != G.edges.end(); ++it) 10 | dist[it->first.b] = min(dist[it->first.b], dist[it->first.a] + it->second); 11 | return dist; 12 | } 13 | 14 | // If one more iteration of Bellman-Ford updates the distance to a node, there is a negative cycle. 15 | bool HasNegativeCycle(const Graph& G, const vector& dist) 16 | { 17 | for (ConstEdgeIterator it = G.edges.begin(); it != G.edges.end(); ++it) 18 | if (dist[it->first.a] + it->second < dist[it->first.b]) return true; 19 | return false; 20 | } 21 | -------------------------------------------------------------------------------- /2d_geometry/dist_2d.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Distance between two points in 2D 2 | ================================================================= 3 | Description: Computes the distance between two points 4 | 5 | Complexity: O(1) 6 | ----------------------------------------------------------------- 7 | Author: Gilbert Lee 8 | Date: Sept 8, 2002 9 | References: 10 | ----------------------------------------------------------------- 11 | Reliability: 0 12 | Notes: 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | #define SQR(x) ((x)*(x)) 19 | 20 | typedef struct{ 21 | double x, y; 22 | } Point; 23 | 24 | double dist_2d(Point a, Point b){ 25 | return sqrt(SQR(a.x-b.x)+SQR(a.y-b.y)); 26 | } 27 | 28 | int main(){ 29 | Point a, b; 30 | 31 | while(scanf("%lf %lf %lf %lf", &a.x, &a.y, &b.x, &b.y) == 4){ 32 | printf("Distance = %f\n", dist_2d(a,b)); 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /misc/strrev.c: -------------------------------------------------------------------------------- 1 | /* Miscellaneous: String Reverse 2 | ================================================================= 3 | Description: Given a string of characters, reverse it. 4 | 5 | Complexity: O(N) 6 | ----------------------------------------------------------------- 7 | Author: Ashley Zinyk 8 | Date: March 14, 2003 9 | References: 10 | ----------------------------------------------------------------- 11 | Reliability: 1 (Spain 483) 12 | Notes: This is extremely simple but sometimes you forget. 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | char *strrev(char *a) { 19 | int i, n = strlen(a); 20 | char tmp; 21 | 22 | for (i = 0; i < n/2; i++) { 23 | tmp = a[i]; 24 | a[i] = a[n-i-1]; 25 | a[n-i-1] = tmp; 26 | } 27 | return a; 28 | } 29 | 30 | int main() { 31 | char word[1000]; 32 | 33 | while (scanf("%s",word)==1) 34 | printf("%s\n",strrev(word)); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /world_finals/src/code/Misc/javaExample.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.InputStreamReader; 3 | import java.util.GregorianCalendar; 4 | import java.util.Scanner; 5 | class Main { 6 | public static void main (String args[]) { 7 | Scanner scanner = new Scanner(System.in); 8 | int T = scanner.nextInt(); 9 | // Different option for input. 10 | BufferedReader inputHandler = new BufferedReader(new InputStreamReader(System.in)); 11 | try { 12 | String line = inputHandler.readLine(); 13 | // Do more 14 | } catch (Exception e) { // Better not reach here 15 | } 16 | } 17 | GregorianCalendar createCal(int year, int zeroIndexMonth, int day, int dayIncrease) 18 | GregorianCalendar cal = new GregorianCalendar(year, zeroIndexMonth, day); 19 | cal.add(Calendar.DAY_OF_MONTH, dayIncrease); 20 | return cal; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /world_finals/src/code/Graph/mst.cpp: -------------------------------------------------------------------------------- 1 | #define MAXN 1000 2 | #define MAXM 1000000 3 | #define EPS 1e-8 4 | int n; 5 | struct Edge { 6 | int u, v; /* Edge between u, v with weight w */ 7 | double w; 8 | }; 9 | int sets[MAXN]; 10 | Edge edge[MAXM], treeedge[MAXN]; 11 | int numedge; 12 | int getRoot(int x) { 13 | if(sets[x] < 0) return x; 14 | return sets[x] = getRoot(sets[x]); 15 | } 16 | void Union(int a, int b) { 17 | int ra = getRoot(a); 18 | int rb = getRoot(b); 19 | if(ra != rb) { 20 | sets[ra] += sets[rb]; 21 | sets[rb] = ra; 22 | } 23 | } 24 | double mintree() { 25 | double weight = 0.0; 26 | int i, count; 27 | sort(edge, edge + numedge, [](auto a, auto b) { return a.w < b.w; }); 28 | for(i = count = 0; count < n - 1; i++) { 29 | if(getRoot(edge[i].u) != getRoot(edge[i].v)) { 30 | Union(edge[i].u, edge[i].v); 31 | weight += edge[i].w; 32 | treeedge[count++] = edge[i]; 33 | } 34 | } 35 | return weight; 36 | } 37 | -------------------------------------------------------------------------------- /graph/kruskal/kruskal.cpp: -------------------------------------------------------------------------------- 1 | #include "../graph.cpp" 2 | #include "../../data/disjoint/disjoint.cpp" 3 | 4 | #include 5 | 6 | // Comparison function for sorting edges by edge weight. 7 | bool EdgeWeightComp(const WeightedEdge& L, const WeightedEdge& R) 8 | { 9 | return L.second < R.second; 10 | } 11 | 12 | // Kruskal's MST algorithm using Disjoint Sets data structure. 13 | vector KruskalMST(const Graph& G) 14 | { 15 | DisjointSets DS(G.nodes.size()); 16 | vector MST; 17 | MST.reserve(G.NumNodes() - 1); 18 | for (ConstNodeIterator it = G.nodes.begin(); it != G.nodes.end(); ++it) 19 | DS.MakeSet(*it); 20 | vector edges = G.edges; 21 | sort(edges.begin(), edges.end(), EdgeWeightComp); 22 | for (int i = 0; i < edges.size(); ++i) { 23 | if (DS.Find(edges[i].first.a) != DS.Find(edges[i].first.b)) { 24 | MST.push_back(edges[i]); 25 | DS.Union(edges[i].first.a, edges[i].first.b); 26 | } 27 | } 28 | return MST; 29 | } 30 | -------------------------------------------------------------------------------- /2d_geometry/area_regpoly.c: -------------------------------------------------------------------------------- 1 | /* 2D Geometry: Area of a regular polygon 2 | ================================================================= 3 | Description: Returns the area of a regular n-gon with side 4 | length s. 5 | 6 | Complexity: O(1) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Sept 7, 2002 10 | References: http://mathworld.wolfram.com/Area.html 11 | ----------------------------------------------------------------- 12 | Reliability: 0 (Sept 2002) 13 | Notes: 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | double PI; 20 | 21 | double area_regpoly(int n, double s){ 22 | return n < 3 ? 0 : n*s*s/tan(PI/n)/4; 23 | } 24 | 25 | int main(){ 26 | int n; 27 | double s; 28 | 29 | PI = acos(-1); 30 | while(scanf("%d %lf", &n, &s) == 2) 31 | printf("Regular %d-gon has area: %f\n", n, area_regpoly(n,s)); 32 | return 0; 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /world_finals/src/code/NumberTheory/Chinese remaindering and ext. Euclidean.cpp: -------------------------------------------------------------------------------- 1 | typedef long long int LLI; 2 | LLI mod(LLI a, LLI m) { return ((a % m) + m) % m; } 3 | // Assumes non-negative input. Returns d such that d=a*ss+b*tt 4 | LLI gcdex(LLI a, LLI b, LLI &ss, LLI &tt) { 5 | if(b == 0) { 6 | ss = 1; 7 | tt = 0; 8 | return a; 9 | } 10 | LLI g = gcdex(b, a % b, tt, ss); 11 | tt = tt - (a / b) * ss; 12 | return g; 13 | } 14 | // Returns x such that 0<=x &a, vector &m) { 18 | LLI g, s, t, a_tmp, m_tmp; 19 | a_tmp = mod(a[0], m[0]); 20 | m_tmp = m[0]; 21 | for(int i = 1; i < a.size(); ++i) { 22 | g = gcdex(m_tmp, m[i], s, t); 23 | if((a_tmp - a[i]) % g) return -1; 24 | a_tmp = mod(a_tmp + (a[i] - a_tmp) / g * s * m_tmp, m_tmp / g * m[i]); 25 | m_tmp = m[i] * m_tmp / gcdex(m[i], m_tmp, s, t); 26 | } 27 | return a_tmp; 28 | } 29 | -------------------------------------------------------------------------------- /2d_geometry/area_ellipse.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Area of an Ellipse 2 | ================================================================= 3 | Description: Given the quadratic form of an ellipse: 4 | ax^2 + bxy + cy^2 = 1 5 | returns the area of the ellipse 6 | 7 | Complexity: O(1) 8 | ----------------------------------------------------------------- 9 | Author: Gilbert Lee 10 | Date: Sept 7, 2002 11 | References: http://mathworld.wolfram.com/Ellipse.html 12 | ----------------------------------------------------------------- 13 | Reliability: 0 14 | Notes: 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | double PI; 21 | 22 | double area_gen_ellipse(double a, double b, double c){ 23 | return 2*PI / (sqrt(4*a*c-b*b)); 24 | } 25 | 26 | int main(){ 27 | double a, b, c; 28 | 29 | PI = acos(-1); 30 | while(scanf("%lf %lf %lf", &a, &b, &c) == 3){ 31 | printf("Area of Ellipse is %f.\n", area_gen_ellipse(a,b,c)); 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /misc/bitcount.c: -------------------------------------------------------------------------------- 1 | /* Miscellaneous: Bit Count 2 | ================================================================= 3 | Description: Takes an integer value and returns the number of 4 | bits that are set to one. 5 | 6 | Complexity: O(N) where N is the number of '1' bits. 7 | ----------------------------------------------------------------- 8 | Author: Patrick Earl 9 | Date: Sept 25, 2002 10 | ----------------------------------------------------------------- 11 | Reliability: 0 12 | Notes: As is, it accepts large unsigned values. It can be 13 | modified to check larger integers by using long long 14 | instead of int. 15 | */ 16 | 17 | #include 18 | 19 | int bitcount(int a){ 20 | int c = 0; 21 | 22 | while(a){ 23 | c++; 24 | a &= a-1; 25 | } 26 | return c; 27 | } 28 | 29 | int main(){ 30 | int a; 31 | 32 | while(scanf("%d", &a) == 1){ 33 | printf("Number of 1 bits in %d is %d\n", a, bitcount(a)); 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /num_theory/num_divisors.c: -------------------------------------------------------------------------------- 1 | /* Number Theory: Number of Divisors 2 | ================================================================= 3 | Description: Returns the number of divisors for a positive 4 | integer N 5 | 6 | Complexity: O(sqrt(N)) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Sept 8, 2002 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 0 13 | Notes: 14 | */ 15 | 16 | #include 17 | 18 | int num_divisors(int n){ 19 | int i, count, res = 1; 20 | 21 | for(i = 2; i*i <= n; i++){ 22 | count = 0; 23 | while(!(n%i)){ 24 | n /= i; 25 | count++; 26 | } 27 | if(count) res *= (count+1); 28 | } 29 | if(n > 1) res *= 2; 30 | return res; 31 | } 32 | 33 | int main(){ 34 | int n; 35 | 36 | while(scanf("%d", &n) == 1){ 37 | printf("%d has %d positive divisors\n", n, num_divisors(n)); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Convex-hull.cpp: -------------------------------------------------------------------------------- 1 | #include "Basics.cpp" 2 | // Assumes pts.size()>0 and returns ccw convex hull with no 3 | // 3 collinear points and with duplicated left most side node 4 | int comp(point &a, point &b) { 5 | if(abs(a.real() - b.real()) > eps) return a.real() < b.real(); 6 | if(abs(a.imag() - b.imag()) > eps) return a.imag() < b.imag(); 7 | return 0; 8 | } 9 | inline vector convexhull(vector &pts) { 10 | sort(pts.begin(), pts.end(), comp); 11 | vector lower, upper; 12 | for(int i = 0; i < (int)pts.size(); i++) { 13 | // <-eps include all points on border 14 | while(lower.size() >= 2 && cross(lower.back() - lower[lower.size() - 2], pts[i] - lower.back()) < eps) lower.pop_back(); 15 | // >eps include all points on border 16 | while(upper.size() >= 2 && cross(upper.back() - upper[upper.size() - 2], pts[i] - upper.back()) > -eps) upper.pop_back(); 17 | lower.push_back(pts[i]); 18 | upper.push_back(pts[i]); 19 | } 20 | lower.insert(lower.end(), upper.rbegin() + 1, upper.rend()); 21 | return lower; 22 | } 23 | -------------------------------------------------------------------------------- /world_finals/src/code/Misc/C++ IO format: -------------------------------------------------------------------------------- 1 | #include // include everything 2 | freopen("test.in","r",stdin); 3 | freopen("test.out","w",stdout); 4 | cout << fixed << setprecision(7) << M_PI << endl; // 3.1415927 5 | cout << scientific << M_PI << endl; // 3.1415927e+000 6 | int x=15, y=12094; 7 | cout << setbase(10) << x << " " << y << endl; // 15 12094 8 | cout << setbase(8) << x << " " << y << endl; // 17 27476 9 | cout << setbase(16) << x << " " << y << endl; // f 2f3e 10 | x=5; y=9; 11 | cout << setfill('0') << setw(2) << x << ":" << setw(2) << y << 12 | endl; // 05:09 13 | printf ("%10d\n", 111); // 111 14 | printf ("%010d\n", 111); //0000000111 15 | printf ("%d %x %X %o\n", 200, 200, 200, 200); //200 c8 C8 310 16 | printf ("%010.2f %e %E\n", 1213.1416, 3.1416, 3.1416); 17 | //0001213.14 3.141600e+00 3.141600E+00 18 | printf ("%*.*d\n",10, 5, 111); // 00111 19 | printf ("%-*.*d\n",10, 5, 111); //00111 20 | printf ("%+*.*d\n",10, 5, 111); // +00111 21 | char in[20]; int d; 22 | scanf ("%s %*s %d",in,&d); //<- it's number 5 23 | printf ("%s %d \n", in,d); //it's 5 24 | -------------------------------------------------------------------------------- /2d_geometry/soddy_circ_radius.c: -------------------------------------------------------------------------------- 1 | /* 2D_Geometry: Soddy Circle Radius 2 | ================================================================= 3 | Description: Given three tangent circles, this finds the radius 4 | of the circle that is tangent to the other three. 5 | 6 | Complexity: O(1) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Feb 23, 2003 10 | References: http://mathworld.wolfram.com/FourCoinsProblem.html 11 | http://mathworld.wolfram.com/SoddyCircles.html 12 | ----------------------------------------------------------------- 13 | Reliability: 0 14 | Notes: 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | double soddy_rad(double r1, double r2, double r3){ 21 | return (r1*r2*r3)/(r2*r3+r1*(r2+r3)+2*sqrt(r1*r2*r3*(r1+r2+r3))); 22 | } 23 | 24 | 25 | int main(){ 26 | double r1, r2, r3; 27 | while(scanf("%lf %lf %lf", &r1, &r2, &r3) == 3){ 28 | printf("Soddy circle radius = %f\n", soddy_rad(r1, r2, r3)); 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Segment-segment intersection.cpp: -------------------------------------------------------------------------------- 1 | #include "Line-line intersection.cpp" 2 | // Intersect of segments a-b and c-d 3 | // -2 -> not parallel and no intersection 4 | // -1 -> coincide with no common point 5 | // 0 -> parallel and not coincide 6 | // 1 -> intersected ('p' is intersection of segments) 7 | // 2 -> coincide with common points ('p' is one of the end 8 | // points lying on both segments) 9 | int seg_seg_inter(point a, point b, point c, point d, point &p) { 10 | int s = line_line_inter(a, b, c, d, p); 11 | if(s == 0) return 0; 12 | if(s == -1) { 13 | // '<-eps' excludes endpoints in the coincide case 14 | if(dot(a - c, a - d) < eps) { 15 | p = a; 16 | return 2; 17 | } 18 | if(dot(b - c, b - d) < eps) { 19 | p = b; 20 | return 2; 21 | } 22 | if(dot(c - a, c - b) < eps) { 23 | p = c; 24 | return 2; 25 | } 26 | return -1; 27 | } 28 | // '<-eps' excludes endpoints in intersected case 29 | if(dot(p - a, p - b) < eps && dot(p - c, p - d) < eps) return 1; 30 | return -2; 31 | } 32 | -------------------------------------------------------------------------------- /graph/graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | // Some basic data structures for graph storage. 9 | struct Edge { 10 | Edge(int a, int b) : a(a), b(b) {} 11 | Edge() {} 12 | int a, b; 13 | }; 14 | 15 | typedef pair WeightedEdge; 16 | typedef set::iterator NodeIterator; 17 | typedef set::const_iterator ConstNodeIterator; 18 | typedef vector::iterator EdgeIterator; 19 | typedef vector::const_iterator ConstEdgeIterator; 20 | 21 | // Graph implemented as edge list and node set. 22 | struct Graph { 23 | vector edges; // Weighted directed edges in the graph. 24 | set nodes; // Keep a set of nodes around so we know how many nodes are in the graph. 25 | void AddEdge(int a, int b, int w) 26 | { 27 | nodes.insert(a); nodes.insert(b); 28 | edges.push_back(make_pair(Edge(a,b), w)); 29 | } 30 | void AddBiEdge(int a, int b, int w) { AddEdge(a,b,w); AddEdge(b,a,w); } 31 | int NumEdges() const { return edges.size(); } 32 | int NumNodes() const { return nodes.size(); } 33 | }; 34 | -------------------------------------------------------------------------------- /world_finals/src/code/Misc/Equation solving.cpp: -------------------------------------------------------------------------------- 1 | const double eps = 1e-7; 2 | bool zero(double a) { return (a < eps) && (a > -eps); } 3 | // m = number of equations, n = number of variables, 4 | // a[m][n+1] = coefficients matrix 5 | // Returns double ans[n] containing the solution, if there is no 6 | // solution returns NULL 7 | double *solve(double **a, int m, int n) { 8 | int cur = 0; 9 | for(int i = 0; i < n; ++i) { 10 | for(int j = cur; j < m; ++j) 11 | if(!zero(a[j][i])) { 12 | if(j != cur) swap(a[j], a[cur]); 13 | for(int sat = 0; sat < m; ++sat) { 14 | if(sat == cur) continue; 15 | double num = a[sat][i] / a[cur][i]; 16 | for(int sot = 0; sot <= n; ++sot) a[sat][sot] -= a[cur][sot] * num; 17 | } 18 | cur++; 19 | break; 20 | } 21 | } 22 | for(int j = cur; j < m; ++j) 23 | if(!zero(a[j][n])) return NULL; 24 | double *ans = new double[n]; 25 | for(int i = 0, sat = 0; i < n; ++i) { 26 | ans[i] = 0; 27 | if(sat < m && !zero(a[sat][i])) { 28 | ans[i] = a[sat][n] / a[sat][i]; 29 | sat++; 30 | } 31 | } 32 | return ans; 33 | } 34 | -------------------------------------------------------------------------------- /arithmetic/fast_exp.c: -------------------------------------------------------------------------------- 1 | /* Arithmetic: Fast Exponentition 2 | ================================================================= 3 | Description: Given integer x and nonnegative number N, computes 4 | x^N quickly 5 | 6 | Complexity: O(lg N) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Sept 17, 2002 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 0 13 | Notes: x can be negative. 14 | N >= 0 otherwise routine will infinitely loop 15 | The limit for the results is: 16 | [-9223372036854775808 = -2^63, to 17 | +9223372036854775807 = +2^63 - 1] 18 | */ 19 | 20 | #include 21 | 22 | #define LL long long 23 | 24 | LL fast_exp(int b, int n){ 25 | LL res = 1, x = b, p; 26 | 27 | for(p = n; p; p >>= 1, x *= x) 28 | if(p & 1) res *= x; 29 | 30 | return res; 31 | } 32 | 33 | int main(){ 34 | int b, n; 35 | 36 | while(scanf("%d %d", &b, &n) == 2){ 37 | printf("%d^%d = %Ld\n", b, n, fast_exp(b,n)); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /world_finals/src/code/Misc/Common bugs: -------------------------------------------------------------------------------- 1 | * READ THE STATEMENT AGAIN. TELL YOUR TEAMMATE IF NECESSARY 2 | * Double check spell of literals 3 | * Graph: Multiple components, Multiple edges, Loops 4 | * Geometry: Be careful about +pi,-pi 5 | * Initialization: Use memset/clear(). Don't expect global 6 | variables to be zero. Care about multiple tests. 7 | * Precision and Range: Use long long if necessary 8 | Use python for big numbers. 9 | * Derive recursive formulas that use sum instead of 10 | multiplication to avoid overflow. 11 | * Small cases (n=0,1,negative) 12 | * 0-based <=> 1-based 13 | * Division by zero. Integer division a/(double)b 14 | * Stack overflow (DFS on 1e5) 15 | * Infinite loop? 16 | * array bound check. maxn or x*maxn 17 | * Don't use .size()-1 ! 18 | * “(int)-3 < (unsigned int) 2” is false! 19 | * Check copy-pasted codes! 20 | * Be careful about -0.0 21 | * Remove debug info! 22 | * Output format: Spaces at the end of line. Blank lines. View 23 | the output in VIM if necessary 24 | * Add eps to double before getting floor or round 25 | * If setting a dp table to Inf when executing to avoid returning to this state, should look at using B/DFS instead! 26 | * Make sure you actually use the DP table 27 | -------------------------------------------------------------------------------- /generators/catalan.c: -------------------------------------------------------------------------------- 1 | /* Generator: Catalan Numbers 2 | ================================================================= 3 | Description: Generates the first few catalan numbers 4 | 5 | Complexity: O(n) 6 | ----------------------------------------------------------------- 7 | Author: Ashley Zinyk 8 | Date: Dec 07, 2002 9 | References: None. 10 | ----------------------------------------------------------------- 11 | Reliability: 1 12 | Notes: The sequence of catalan numbers grows pretty quickly. 13 | For n > 33, long longs are too small, so use the same 14 | algorithm with bignum. 15 | 16 | You may want to tweak the zeroth catalan number so that it 17 | has meaning in your application (for instance, how many 18 | ways are there to bracket zero terms? 19 | */ 20 | 21 | #include 22 | 23 | long long int cat[33]; 24 | 25 | void getcat() { 26 | int i; 27 | 28 | cat[0] = cat[1] = 1; 29 | for (i = 2; i < 33; i++) 30 | cat[i] = cat[i-1]*(4*i-6)/i; 31 | } 32 | 33 | int main() { 34 | int i; 35 | 36 | getcat(); 37 | for (i = 0; i < 33; i++) { 38 | printf("%lld\n",cat[i]); 39 | } 40 | 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /combinatorics/permdex_distinct.c: -------------------------------------------------------------------------------- 1 | /* Combinatorics - Permutation index on distinct characters 2 | ================================================================= 3 | Description: Given a string formed of distinct characters, 4 | returns the index of the permutation from 0..N!-1. 5 | 6 | Complexity: O(N^2) where N is size of the string 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Nov 14, 2002 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 0 13 | Notes: This does not work when characters can be the same 14 | for example: "aaba" 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | int permdex (char *s){ 21 | int i, j, size = strlen(s); 22 | int index = 0; 23 | 24 | for (i = 1; i < size; i++){ 25 | for (j = i; j < size; j++) 26 | if (s[i-1] > s[j]) index ++; 27 | index *= size - i; 28 | } 29 | return index; 30 | } 31 | 32 | int main(){ 33 | char s[100]; 34 | 35 | while(scanf(" %s", s) == 1){ 36 | printf("Index of %s = %d\n", s, permdex(s)); 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /num_theory/sum_divisors.c: -------------------------------------------------------------------------------- 1 | /* Number Theory: Sum of divisors 2 | ================================================================= 3 | Description: Returns the sum of all the positive divisors for 4 | a positive integer N 5 | 6 | Complexity: O(sqrt(N)) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Sept 8, 2002 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 2 successful use Oct 2002, Topcoder SRM 101 (450 pt) 13 | (Spain: #382) 14 | Notes: 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #define LL long long 21 | 22 | LL sum_divisors(LL n){ 23 | int i, count; LL res = 1; 24 | 25 | for(i = 2; i*i <= n; i++){ 26 | count = 0; 27 | while(n % i == 0){ 28 | n /= i; 29 | count++; 30 | } 31 | if(count) res *= ((pow(i, count+1)-1)/(i-1)); 32 | } 33 | if(n > 1) res *= ((pow(n, 2)-1)/(n-1)); 34 | return res; 35 | } 36 | 37 | int main(){ 38 | LL n; 39 | 40 | while(scanf("%lld", &n) == 1){ 41 | printf("The sum of all divisors of %lld is %lld\n", n, sum_divisors(n)); 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /num_theory/eulerphi.c: -------------------------------------------------------------------------------- 1 | /* Number Theory: Euler Phi function 2 | ================================================================= 3 | Description: The Euler Phi function returns the number of 4 | positive integers less than N that are relatively 5 | prime to N 6 | 7 | Complexity: O(sqrt(N)) 8 | ----------------------------------------------------------------- 9 | Author: Gilbert Lee 10 | Date: Sept 21, 2002 11 | References: 12 | ----------------------------------------------------------------- 13 | Reliability: 0 14 | Notes: Time estimates: 1 000 0m00.600s 15 | 10 000 0m00.770s 16 | 100 000 0m03.180s 17 | 1 000 000 0m34.270s 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | int phi(int n){ 24 | int i, count, res = 1; 25 | 26 | for(i = 2; i*i <= n; i++){ 27 | count = 0; 28 | while(n % i == 0){ 29 | n /= i; 30 | count++; 31 | } 32 | if(count > 0) res *= (pow(i, count)-pow(i, count-1)); 33 | } 34 | if(n > 1) res *= (n-1); 35 | return res; 36 | } 37 | 38 | int main(){ 39 | int n; 40 | 41 | for(n = 0; n < 10; n++) 42 | printf("Euler phi (%d) = %d\n", n, phi(n)); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /num_theory/isprime.c: -------------------------------------------------------------------------------- 1 | /* Number Theory: Primality Testing 2 | ================================================================= 3 | Description: This routine checks if a positive integer N is a 4 | prime. 5 | 6 | Complexity: O(sqrt(N)) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Sept 21, 2002 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 0 13 | Notes: if 1 is to be considered a prime, set ONEPRIME to 1 14 | - if there is a lot of primality testing to be done 15 | try using primesieve.c instead of isprime.c for 16 | speed reasons. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #define ONEPRIME 0 23 | 24 | int isPrime(int x){ 25 | int i; 26 | if( x == 1 ) return ONEPRIME; 27 | if( x == 2 ) return 1; 28 | if( x % 2 == 0) return 0; 29 | 30 | for(i = 3; i*i <= x; i+=2) 31 | if( x % i == 0) return 0; 32 | return 1; 33 | } 34 | 35 | int main(){ 36 | int x; 37 | 38 | for(x = 1; x < 100; x++){ 39 | if(isPrime(x)) 40 | printf("%d is prime\n", x); 41 | else 42 | printf("%d is not prime\n", x); 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /world_finals/src/code/Combinatorics/(Un)Ranking of K-permutation out of N.cpp: -------------------------------------------------------------------------------- 1 | // Returns 'pi': a k-permutation corresponding to rank 'r' of n objects. 2 | // 'id' should be a full identity permutation of size at least n 3 | void rec_unrank_perm(int n, int k, long long r, vector &id, vector &pi) { 4 | if(k > 0) { 5 | swap(id[n - 1], id[r % n]); 6 | rec_unrank_perm(n - 1, k - 1, r / n, id, pi); 7 | pi.push_back(id[n - 1]); 8 | swap(id[n - 1], id[r % n]); 9 | } 10 | } 11 | long long rec_rank_perm(int n, int k, vector &pirev, vector &pi) { 12 | if(k == 0) return 0; 13 | int s = pi[k - 1]; 14 | swap(pi[k - 1], pi[pirev[n - 1] - (n - k)]); 15 | swap(pirev[s], pirev[n - 1]); 16 | long long ans = s + n * rec_rank_perm(n - 1, k - 1, pirev, pi); 17 | swap(pirev[s], pirev[n - 1]); 18 | swap(pi[k - 1], pi[pirev[n - 1] - (n - k)]); 19 | return ans; 20 | } 21 | // Returns rank of the k-permutaion 'pi' of n objects. 22 | // 'id' should be a full identity permutation of size at least n 23 | long long rank_perm(int n, vector &id, vector pi) { 24 | for(int i = 0; i < pi.size(); i++) id[pi[i]] = i + n - pi.size(); 25 | long long ans = rec_rank_perm(n, pi.size(), id, pi); 26 | for(int v: pi) id[v] = v; 27 | return ans; 28 | } 29 | -------------------------------------------------------------------------------- /world_finals/src/code/String/trie.cpp: -------------------------------------------------------------------------------- 1 | // This Trie is designed for returning the longest 2 | // substring that appears more than once in a string 3 | struct TrieNode { 4 | int cnt; 5 | map child; 6 | TrieNode() { cnt = 0; } 7 | }; 8 | // Need to initialize each time after calling deleteTrie 9 | TrieNode *root = NULL; 10 | string resultString = ""; 11 | int resultCnt = 0; 12 | // start is the start point in s 13 | void insertTrie(string &s, int start) { 14 | if(root == NULL) root = new TrieNode; 15 | TrieNode *current = root; 16 | for(int i = start; i < s.size(); i++) { 17 | if(current->child[s[i]] == NULL) current->child[s[i]] = new TrieNode; 18 | current->child[s[i]]->cnt++; 19 | current = current->child[s[i]]; 20 | } 21 | } 22 | // string tmp="";findLongest(root,tmp); 23 | void findLongest(TrieNode *current, string &s) { 24 | for(auto c: current->child) 25 | if(c.second->cnt > 1) { 26 | s.push_back(c.first); 27 | findLongest(c.second, s); 28 | s.pop_back(); 29 | } 30 | if(s.size() > resultString.size()) { 31 | resultString = s; 32 | resultCnt = current->cnt; 33 | } 34 | } 35 | void deleteTrie(TrieNode *current) { 36 | if(current == NULL) return; 37 | for(auto c: current->child) deleteTrie(c.second); 38 | delete current; 39 | } 40 | -------------------------------------------------------------------------------- /combinatorics/factorial_dig.c: -------------------------------------------------------------------------------- 1 | /* Combinatorics: Digits in N! 2 | ================================================================= 3 | Description: Given N, computes the number of digits that N! will 4 | occupy in base B. 5 | 6 | Complexity: O(N) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee, Ashley Zinyk 9 | Date: Feb 14, 2003 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 1 (Problem B - Big Number Feb 11, 2003) 13 | Notes: The results fit nicely in doubles up to N = 10^7, but 14 | run time may be slow. 15 | 16 | Returns 1 for n < 0, although technically undefined. 17 | The base must be larger than 1. 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | long long fac_digit(int n, int b) { 24 | double sum = 0; int i; 25 | 26 | for (i = 2; i <= n; i++) sum += log(i); 27 | return (long long) floor(1+sum/log(b)); /* don't use ceil! */ 28 | } 29 | 30 | int main() { 31 | int n, b; 32 | 33 | while (scanf("%d %d", &n, &b)==2) { 34 | printf("%d! has %lld symbol(s) when represented " 35 | "in base %d\n", n, fac_digit(n,b), b); 36 | } 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Circle described by two lines and one point.cpp: -------------------------------------------------------------------------------- 1 | #include "Line-line intersection.cpp" 2 | #include "Parabola-line intersection.cpp" 3 | // Returns number of circles that pass through point p and are 4 | // tangent to the lines a-b and c-d 5 | // 'ans' has all possible circles with radius greater than zero 6 | int get_circle(point p, point a, point b, point c, point d, vector &ans) { 7 | point inter; 8 | int st = line_line_inter(a, b, c, d, inter); 9 | if(st == -1) return 0; 10 | d -= c; 11 | b -= a; 12 | vector ta; 13 | if(st == 0) { 14 | point pa = point(0, imag((a - c) / d) / 2) * d + c; 15 | point pb = b + pa; 16 | parabola_line_inter(p, a, a + b, pa, pb, ta); 17 | } else { 18 | if(abs(inter - p) > eps) { 19 | point bi; 20 | bi = polar(1.0, (arg(b) + arg(d)) / 2) + inter; 21 | vector temp; 22 | parabola_line_inter(p, a, a + b, inter, bi, temp); 23 | ta.insert(ta.end(), temp.begin(), temp.end()); 24 | temp.clear(); 25 | bi = polar(1.0, (arg(b) + arg(d) + M_PI) / 2) + inter; 26 | parabola_line_inter(p, a, a + b, inter, bi, temp); 27 | ta.insert(ta.end(), temp.begin(), temp.end()); 28 | } 29 | } 30 | for(point pt: ta) ans.push_back(circle(pt, abs(p - pt))); 31 | return ans.size(); 32 | } 33 | -------------------------------------------------------------------------------- /combinatorics/josephus.c: -------------------------------------------------------------------------------- 1 | /* Combinatorics: Josephus Ring Survivor 2 | ================================================================= 3 | Description: Suppose that there are n people in a ring, [0..n-1]. 4 | Count around the ring, starting from 0, and 5 | dismissing every m-th person. 6 | 7 | Given m, this function builds an array survive[i] 8 | which contains the last person left in the ring if 9 | there were i people to begin with. 10 | 11 | Complexity: O(N) 12 | ----------------------------------------------------------------- 13 | Author: Gilbert Lee 14 | Date: March 01, 2003 15 | References: 16 | ----------------------------------------------------------------- 17 | Reliability: 2 (Spain 151 - Power Crisis) 18 | (Spain 180 - Eeny Meeny) 19 | Notes: - survive[i] is only define when i >= 1 20 | */ 21 | 22 | #include 23 | 24 | #define MAXN 1000005 25 | 26 | int survive[MAXN]; 27 | 28 | void josephus(int n, int m){ 29 | int i; 30 | survive[1] = 0; 31 | for(i = 2; i <= n; i++) 32 | survive[i] = (survive[i-1]+(m%i))%i; 33 | } 34 | 35 | int main(){ 36 | int n, m; 37 | 38 | while(scanf("%d %d", &n, &m)==2){ 39 | josephus(n,m); 40 | printf("Survivor is %d\n", survive[n]); 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /2d_geometry/closest_pt_iline.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Closest Point on Infinite Line 2 | ================================================================= 3 | Description: Given a point C, and an infinite line represented by 4 | points A and B, returns the point P on the line 5 | closest to C. (i.e. CP is orthogonal to AB) 6 | 7 | Complexity: O(1) 8 | ----------------------------------------------------------------- 9 | Author: Ashley Zinyk 10 | Date: Nov 9, 2002 11 | References: 12 | ----------------------------------------------------------------- 13 | Reliability: 0 14 | Notes: Assumes that points A and B are not the same. 15 | */ 16 | 17 | #include 18 | #define SQR(x) ((x)*(x)) 19 | 20 | typedef struct{ 21 | double x, y; 22 | } Point; 23 | 24 | Point closest_pt_iline(Point a, Point b, Point c) { 25 | Point p; 26 | double dp; 27 | 28 | b.x -= a.x; 29 | b.y -= a.y; 30 | dp = (b.x*(c.x-a.x) + b.y*(c.y-a.y)) / (SQR(b.x)+SQR(b.y)); 31 | p.x = b.x*dp + a.x; 32 | p.y = b.y*dp + a.y; 33 | return p; 34 | } 35 | 36 | int main() { 37 | Point a, b, c, p; 38 | 39 | while (scanf("%lf %lf %lf %lf %lf %lf", 40 | &a.x, &a.y, &b.x, &b.y, &c.x, &c.y) == 6){ 41 | p = closest_pt_iline(a,b,c); 42 | printf("%g %g\n", p.x, p.y); 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /world_finals/src/code/Graph/Steiner.cpp: -------------------------------------------------------------------------------- 1 | // Given a weighted undirected graph G = (V, E) and a subset S of V, 2 | // finds a minimum weight tree T whose vertices are a superset of S. 3 | // NP-hard -- this is a pseudo-polynomial algorithm. 4 | // Minimum stc[(1<>= 1) 20 | ; 21 | for(int v = 0; v < n; ++v) stc[i][v] = d[v][u]; 22 | } else 23 | for(int v = 0; v < n; ++v) { 24 | stc[i][v] = 0xffffff; 25 | for(int j = 1; j < i; ++j) 26 | if((j | i) == i) { 27 | int x1 = j, x2 = i & (~j); 28 | for(int w = 0; w < n; ++w) stc[i][v] = min(stc[i][v], d[v][w] + stc[x1][w] + stc[x2][w]); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /graph/dijkstra/dijkstra_min.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | struct Graph { 11 | Graph(int N) : graph(N, list >()) {} 12 | void addEdge(int src, int dst, int len) { graph[src].push_back(make_pair(dst, len)); } 13 | vector > > graph; 14 | }; 15 | 16 | vector Dijkstra(const Graph& G, int src) 17 | { 18 | vector visited(G.graph.size(), false); 19 | vector distance(G.graph.size(), numeric_limits::max()); 20 | vector prev(G.graph.size(), -1); 21 | priority_queue, vector >, greater > > q; 22 | 23 | distance[src] = 0; 24 | q.push(make_pair(0, src)); 25 | 26 | while (!q.empty()) { 27 | pair entry = q.top(); q.pop(); 28 | int cur = entry.second; 29 | if (visited[cur]) continue; 30 | for (list >::const_iterator it = G.graph[cur].begin(); it != G.graph[cur].end(); ++it) { 31 | if (visited[it->first]) continue; 32 | if (distance[cur] + it->second < distance[it->first]) { 33 | distance[it->first] = distance[cur] + it->second; 34 | prev[it->first] = cur; 35 | q.push(make_pair(distance[it->first], it->first)); 36 | } 37 | } 38 | visited[cur] = true; 39 | } 40 | return prev; 41 | } 42 | -------------------------------------------------------------------------------- /combinatorics/binomial.c: -------------------------------------------------------------------------------- 1 | /* Arithmetic: Binomial coefficient 2 | ================================================================= 3 | Description: Given n objects in total, returns the number of ways 4 | to choose k of those objects with no regard to order 5 | 6 | Complexity: O(N^2) to generate table 7 | O(1) lookup cost 8 | ----------------------------------------------------------------- 9 | Author: Gilbert Lee 10 | Date: Sept 16, 2002 11 | References: 12 | ----------------------------------------------------------------- 13 | Reliability: 0 14 | Notes: This program is accurate to up to n = 68. At n = 69 15 | there is a slight deviation. Note that all results 16 | with n <= 68 are representable exactly by 17 | floating point. 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #define MAXN 100 24 | 25 | long double bin[MAXN+1][MAXN+1]; 26 | 27 | void getBinCoeff(){ 28 | int i, k; 29 | 30 | for(k = 0; k <= MAXN; k++){ 31 | bin[k][0] = bin[k][k] = 1; 32 | for(i = 1; i < k; i++) 33 | bin[k][i] = bin[k-1][i-1]+bin[k-1][i]; 34 | } 35 | } 36 | 37 | int main(){ 38 | int n,k; 39 | 40 | getBinCoeff(); 41 | 42 | while(scanf("%d %d", &n, &k) == 2){ 43 | printf("%d C %d = %.0Lf\n", n,k,bin[n][k]); 44 | } 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /num_theory/farey.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Farey Sequence Generator: 3 | 4 | Author: Zachary Friggstad 5 | Date: Aug, 2008 6 | 7 | --------------------------------------------------------------- 8 | 9 | The Farey Sequence of order n is the list of 10 | all reduced fractions between 0 and 1 (inclusive) 11 | in sorted order. 12 | 13 | e.g. order 6: 14 | 0/1, 1/6, 1/5, 1/4, 2/5, 1/3, 1/2, 2/3, 3/5, 3/4, 4/5, 5/6, 1/1 15 | 16 | Given any positive integer n, this algorithm will generate 17 | the Farey sequence in order with one term being generated per 18 | loop iteration. 19 | 20 | --------------------------------------------------------------- 21 | 22 | Complexity: 23 | - linear time in the size of the output 24 | - constant space 25 | 26 | Reference: 27 | "Introduction to the Theory of Numbers" - Hardy & Wright 28 | 29 | Reliablity: 30 | UVa - 10408 31 | */ 32 | 33 | 34 | #include 35 | #include 36 | 37 | using namespace std; 38 | 39 | void farey(int n) { 40 | int h = 0, k = 1, x = 1, y = 0; 41 | 42 | do { 43 | cout << h << '/' << k << endl; 44 | 45 | int r = (n-y)/k; 46 | y += r*k; 47 | x += r*h; 48 | 49 | swap(x,h); 50 | swap(y,k); 51 | x = -x; 52 | y = -y; 53 | } while (k > 1); 54 | cout << "1/1" << endl; 55 | } 56 | 57 | int main() { 58 | int n; 59 | while (cin >> n) 60 | farey(n); 61 | } 62 | -------------------------------------------------------------------------------- /2d_geometry/area_triangle.cpp: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Area of a Triangle - 3 points 2 | ================================================================= 3 | Description: Given three vertices a triangle, returns the area 4 | of the triangle. 5 | 6 | Complexity: O(1) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Sept 7, 2002 10 | References: 11 | ----------------------------------------------------------------- 12 | Updated By: Morgan Redshaw 13 | Date: Jan 8, 2015 14 | ----------------------------------------------------------------- 15 | Reliability: 0 16 | Notes: 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | using namespace std; 24 | 25 | typedef complex Point; 26 | 27 | 28 | inline double cross(const Point &a, const Point &b) { 29 | return imag(conj(a)*b); 30 | } 31 | 32 | double area_triangle(Point a, Point b, Point c){ 33 | double area; 34 | 35 | area = cross(b - a, c - a); 36 | 37 | return fabs(area) / 2; 38 | } 39 | 40 | 41 | int main() 42 | { 43 | double ax, ay, bx, by, cx, cy; 44 | 45 | while (cin >> ax >> ay >> bx >> by >> cx >> cy) 46 | { 47 | Point a(ax, ay), b(bx, by), c(cx, cy); 48 | cout << "Area of triangle = " << area_triangle(a, b, c) << '\n'; 49 | } 50 | 51 | return 0; 52 | } -------------------------------------------------------------------------------- /world_finals/src/code/Geometry/Parabola-line intersection.cpp: -------------------------------------------------------------------------------- 1 | #include "Basics.cpp" 2 | // Find intersection of the line d-e and the parabola that 3 | // is defined by point 'p' and line a-b 4 | // Returns the number of intersections 5 | // 'ans' has intersection points 6 | int parabola_line_inter(point p, point a, point b, point d, point e, vector &ans) { 7 | b = b - a; 8 | p /= b; 9 | a /= b; 10 | d /= b; 11 | e /= b; 12 | a -= p; 13 | d -= p; 14 | e -= p; 15 | point n = (e - d) * point(0, 1); 16 | double c = -dot(n, e); 17 | if(abs(n.imag()) < eps) { 18 | if(abs(a.imag()) > eps) { 19 | double x = -c / n.real(); 20 | ans.push_back(point(x, a.imag() / 2 - x * x / (2 * a.imag()))); 21 | } 22 | } else { 23 | double aa = 1; 24 | double bb = -2 * a.imag() * n.real() / n.imag(); 25 | double cc = -2 * a.imag() * c / n.imag() - a.imag() * a.imag(); 26 | double delta = bb * bb - 4 * aa * cc; 27 | if(delta > -eps) { 28 | if(delta < 0) delta = 0; 29 | delta = sqrt(delta); 30 | double x = (-bb + delta) / (2 * aa); 31 | ans.push_back(point(x, (-c - n.real() * x) / n.imag())); 32 | if(delta > eps) { 33 | double x = (-bb - delta) / (2 * aa); 34 | ans.push_back(point(x, (-c - n.real() * x) / n.imag())); 35 | } 36 | } 37 | } 38 | for(int i = 0; i < ans.size(); i++) ans[i] = (ans[i] + p) * b; 39 | return ans.size(); 40 | } 41 | -------------------------------------------------------------------------------- /world_finals/src/code/Misc/fft.cpp: -------------------------------------------------------------------------------- 1 | using ld = double; // can always try long double if you are concerned 2 | using cplx = complex; 3 | using vc = vector; 4 | // Compute the (I)FFT of f, store in v. 5 | // f.size() *MUST* be a power of 2 6 | void fft(const vc &f, vc &v, bool invert) { 7 | int n = f.size(); 8 | assert(n > 0 && (n & (n - 1)) == 0); 9 | v.resize(n); 10 | for(int i = 0; i < n; ++i) { 11 | int r = 0, k = i; 12 | for(int j = 1; j < n; j <<= 1, r = (r << 1) | (k & 1), k >>= 1) 13 | ; 14 | v[i] = f[r]; 15 | } 16 | for(int m = 2; m <= n; m <<= 1) { 17 | int mm = m >> 1; 18 | cplx zeta = polar(1, (invert ? 2 : -2) * M_PI / m); 19 | for(int k = 0; k < n; k += m) { 20 | cplx om = 1; 21 | for(int j = 0; j < mm; ++j, om *= zeta) { 22 | cplx tl = v[k + j], th = om * v[k + j + mm]; 23 | v[k + j] = tl + th; 24 | v[k + j + mm] = tl - th; 25 | } 26 | } 27 | } 28 | if(invert) 29 | for(auto &z: v) z /= ld(n); // normalize for ifft 30 | } 31 | // Convolve f and g, placing the result in res. 32 | // f and g should be the same length. If they are not, just pad them 33 | // up to the nearest power of two after your desired output size. 34 | void convolve(vc &f, vc &g, vc &res) { 35 | vc tmp(f.size()); 36 | fft(f, tmp, false); 37 | fft(g, res, false); 38 | for(int i = 0; i < f.size(); ++i) tmp[i] *= res[i]; 39 | fft(tmp, res, true); 40 | } 41 | -------------------------------------------------------------------------------- /2d_geometry/dist_iline.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Distance from a point to an infinte line 2 | ================================================================= 3 | Description: Calculates the minimum(orthogonal) distance from a 4 | point P to an infinite line. The line is defined 5 | by two points A and B. 6 | 7 | Complexity: O(1) 8 | ----------------------------------------------------------------- 9 | Author: Howard Cheng, Gilbert Lee 10 | Date: Sept 8, 2002 11 | References: http://www.exaflop.org/docs/cgafaq/cga1.html 12 | ----------------------------------------------------------------- 13 | Reliability: 0 14 | Notes: Assumes that point A != point B, otherwise the line 15 | would not be properly defined -> returns dist=nan 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | typedef struct{ 22 | double x,y; 23 | } Point; 24 | 25 | #define SQR(x) ((x)*(x)) 26 | 27 | double dist_2d(Point a, Point b){ 28 | return sqrt(SQR(a.x-b.x)+SQR(a.y-b.y)); 29 | } 30 | 31 | double dist_iline(Point a, Point b, Point p){ 32 | return fabs(((a.y-p.y)*(b.x-a.x)- 33 | (a.x-p.x)*(b.y-a.y)) 34 | /dist_2d(a,b)); 35 | } 36 | 37 | int main(){ 38 | Point a, b, p; 39 | 40 | while(scanf("%lf %lf %lf %lf %lf %lf", 41 | &a.x, &a.y, &b.x, &b.y, &p.x, &p.y) == 6){ 42 | printf("Distance = %f\n", dist_iline(a,b,p)); 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /num_theory/extended_euclid.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Extended Euclidean Algortihm 3 | 4 | Author: Zac Friggstad 5 | 6 | 1) Given nonnegative integers a, b: 7 | gcd_ex(a, b, s, t) returns g = gcd(a,b) and sets s,t such that a*s + b*t = g 8 | Guaranteed all intermediate values in the calculation are <= max(a, b) 9 | 10 | 2) Given arbitrary integers a, b: 11 | gcd_ex_any(a, b, s, t) returns g = gcd(|a|, |b|) and sets s, t such that 12 | a*s + b*t = g 13 | Guaranteed all intermediate values in the calculation are <= max(|a|, |b|) 14 | 15 | Running time of both: O(log(a) + log(b)) 16 | 17 | Reliability: UVa 10104 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | using namespace std; 24 | 25 | int gcd_ex(int a, int b, int& s, int& t) { 26 | int r0 = a, r1 = b, q; 27 | int s0 = 1, s1 = 0; 28 | int t0 = 0, t1 = 1; 29 | 30 | //invariant: ri = a*si + b*ti for both i = 0 and i = 1 31 | while (r1) { 32 | q = r0 / r1; 33 | 34 | r0 -= q*r1; 35 | swap(r0, r1); 36 | 37 | s0 -= q*s1; 38 | swap(s0, s1); 39 | 40 | t0 -= q*t1; 41 | swap(t0, t1); 42 | } 43 | 44 | //now r0 = gcd(a, b) 45 | s = s0; 46 | t = t0; 47 | 48 | return r0; 49 | } 50 | 51 | int gcd_ex_any(int a, int b, int& s, int& t) { 52 | int g = gcd_ex(abs(a), abs(b), s, t); 53 | if (a < 0) s = -s; 54 | if (b < 0) t = -t; 55 | 56 | return g; 57 | } 58 | -------------------------------------------------------------------------------- /3d_geometry/greatcircle.c: -------------------------------------------------------------------------------- 1 | /* 3d geometry: Great Circle 2 | ================================================================= 3 | Description: Given the latitude and longitude of two points in 4 | degrees, calculates the distance over the sphere 5 | between them. Latitude is given in the range 6 | [-90, 90] degrees, and Longitude is given in the 7 | range [-180,180] degrees. 8 | 9 | Complexity: O(1) 10 | ----------------------------------------------------------------- 11 | Author: Broderick Arneson 12 | Date: October 4th, 2002. 13 | References: Page on the net 14 | ----------------------------------------------------------------- 15 | Reliability: Spain 10316 16 | Notes: - Set radius to what you need. 17 | 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | double pi; 24 | 25 | double greatcircle (double lat1, double long1, 26 | double lat2, double long2) { 27 | 28 | double radius = 1.0; 29 | 30 | double a = pi*(lat1/180.0); 31 | double b = pi*(lat2/180.0); 32 | double c = pi*((long2-long1)/180.0); 33 | return radius*acos(sin(a)*sin(b) + cos(a)*cos(b)*cos(c)); 34 | } 35 | 36 | int main () { 37 | double lat1, lat2, long1, long2; 38 | 39 | pi = acos(-1); 40 | while (scanf("%lf %lf %lf %lf ",&lat1,&long1,&lat2,&long2)==4) { 41 | d = greatcircle(lat1, long1, lat2, long2); 42 | printf("Great Circle Distance = %.5lf\n", d); 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /2d_geometry/reflect.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Reflect a point across a line 2 | ================================================================= 3 | Description: Given a line defined by two points A and B, and 4 | another point c, returns the reflection of point C 5 | across the line. 6 | 7 | Assumes that the A and B are different 8 | 9 | Complexity: O(1) 10 | ----------------------------------------------------------------- 11 | Author: Ashley Zinyk 12 | Date: Nov 9, 2002 13 | References: 14 | ----------------------------------------------------------------- 15 | Reliability: 0 16 | Notes: 17 | */ 18 | 19 | #include 20 | #define SQR(x) ((x)*(x)) 21 | 22 | typedef struct{ 23 | double x, y; 24 | } Point; 25 | 26 | Point closest_pt_iline(Point a, Point b, Point c) { 27 | Point p; 28 | double dp; 29 | 30 | b.x -= a.x; 31 | b.y -= a.y; 32 | dp = (b.x*(c.x-a.x) + b.y*(c.y-a.y)) / (SQR(b.x)+SQR(b.y)); 33 | p.x = b.x*dp + a.x; 34 | p.y = b.y*dp + a.y; 35 | return p; 36 | } 37 | 38 | Point reflect(Point a, Point b, Point c) { 39 | Point d, p; 40 | 41 | d = closest_pt_iline(a,b,c); 42 | p.x = 2.0*d.x - c.x; 43 | p.y = 2.0*d.y - c.y; 44 | return p; 45 | } 46 | 47 | int main() { 48 | Point a, b, c, d; 49 | while (scanf("%lf %lf %lf %lf %lf %lf", 50 | &a.x, &a.y, &b.x, &b.y, &c.x, &c.y)==6) { 51 | d = reflect(a,b,c); 52 | printf("%g %g\n", d.x, d.y); 53 | } 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /Search/queen.c: -------------------------------------------------------------------------------- 1 | /* Search: N non-attacking Queens 2 | ================================================================= 3 | Description: The following is a template for finding valid 4 | configurations for the N-Queens problem. 5 | 6 | Complexity: O(exponential) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Mar 12, 2003 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 13 | Notes: rows/cols labelled 0..n-1 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #define MAXN 100 21 | 22 | int S[MAXN], used[MAXN], n, total; 23 | 24 | void nQueens(int pos){ 25 | int i, j; 26 | if(pos == n){ 27 | total++; 28 | for(i = 0; i < n; i++) 29 | printf("(%d,%d)%c", i, S[i], i == n-1 ? '\n' : ' '); 30 | return; 31 | } 32 | for(i = 0; i < n; i++){ 33 | if(used[i]) continue; 34 | for(j = 0; j < pos; j++) 35 | if(pos-j == abs(i-S[j])) break; 36 | if(j == pos){ 37 | S[pos] = i; 38 | used[i] = 1; 39 | nQueens(pos+1); 40 | used[i] = 0; 41 | } 42 | } 43 | } 44 | 45 | int main(){ 46 | while(scanf("%d", &n) == 1){ 47 | memset(used, 0, sizeof(used)); 48 | total = 0; 49 | nQueens(0); /* Call this to start recursion */ 50 | printf("Total valid configurations for n=%d: %d\n", n,total); 51 | } 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /data_structures/fenwick_tree.cpp: -------------------------------------------------------------------------------- 1 | /* Author: Ian DeHaan, 2019 2 | 3 | Fenwick Tree data structure. Allows to update index and get sum 4 | of array up to index in logarithmic time. 5 | 6 | Complexity: O(n log n) to build the tree 7 | O(log n) to update a value 8 | O(log n) to get sum 9 | 10 | Reliability: 11 | fenwick - Open Kattis 12 | moviecollection - Open Kattis 13 | */ 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | struct FenwickTree { 19 | int n; 20 | vector ftree; 21 | 22 | // Gets sum up to and INCLUDING index 23 | long long sum(int index) { 24 | long long out = 0; 25 | index++; 26 | while (index > 0) { 27 | out += ftree[index]; 28 | index -= index & (-index); 29 | } 30 | return out; 31 | } 32 | 33 | // Adds delta to value at index 34 | void update(int index, long long delta) { 35 | index++; 36 | while (index <= n) { 37 | ftree[index] += delta; 38 | index += index & (-index); 39 | } 40 | } 41 | 42 | // Call this first or the rest won't like you 43 | void construct(long long vals[], int n) { 44 | this->n = n; 45 | ftree.resize(n+1); 46 | for (int i = 1; i <= n; i++) { 47 | ftree[i] = 0; 48 | } 49 | 50 | for (int i = 0; i < n; i++) { 51 | update(i, vals[i]); 52 | } 53 | } 54 | }; -------------------------------------------------------------------------------- /2d_geometry/angle_2d180.cc: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Angle between three points (180 degrees or PI rads) 2 | ================================================================= 3 | Description: Given 3 points A, B, C, it returns the magnitude of 4 | angle ABC in radians. 5 | 6 | Will only return the angle 0 <= theta <= PI. 7 | 8 | Complexity: O(1) 9 | ----------------------------------------------------------------- 10 | Author: Scott Crosswhite 11 | Date: October 19, 2003 12 | References: 13 | ----------------------------------------------------------------- 14 | Reliability: 0 15 | Notes: Uses the Cosine Law, c^2 = a^2 + b^2 - 2ab cos C. 16 | Presumes that d(A,B) and d(B,C) are non-zero. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #define SQR(x) ((x)*(x)) 24 | 25 | typedef struct { 26 | double x, y; 27 | } Point; 28 | 29 | double dist_2d (Point a, Point b) { 30 | return sqrt(SQR(a.x-b.x)+SQR(a.y-b.y)); 31 | } 32 | 33 | double angle2d180 (Point A, Point B, Point C) { 34 | double a = dist_2d(A,B), b = dist_2d(B,C), c = dist_2d(A,C); 35 | return acos((SQR(c)-SQR(a)-SQR(b)) / (-2*a*b)); 36 | } 37 | 38 | int main () { 39 | Point a, b, c; 40 | printf("Enter A, B, C:\n"); 41 | while (scanf("%lf %lf %lf %lf %lf %lf", 42 | &a.x, &a.y, &b.x, &b.y, &c.x, &c.y) == 6) { 43 | printf("Angle ABC in radians = %f\n", angle2d180(a,b,c)); 44 | } 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /2d_geometry/angle_2d.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Angle between three points 2 | ================================================================= 3 | Description: Given 3 points A, B, C, it returns the magnitude of 4 | angle ABC in radians. 5 | 6 | Will only return the angle 0 <= theta <= PI/2. 7 | 8 | Complexity: O(1) 9 | ----------------------------------------------------------------- 10 | Author: Gilbert Lee 11 | Date: Nov 14, 2002 12 | References: 13 | ----------------------------------------------------------------- 14 | Reliability: 0 15 | Notes: Uses vectors to calculate the angle: 16 | a . b = |a| * |b| * cos(theta) --> 17 | theta = acos(a . b / (|a| * |b|)) 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #define SQR(x) ((x)*(x)) 24 | 25 | typedef struct { 26 | double x, y; 27 | } Point; 28 | 29 | double angle2d(Point a, Point b, Point c){ 30 | double dx1 = a.x - b.x, dy1 = a.y - b.y; 31 | double dx2 = c.x - b.x, dy2 = c.y - b.y; 32 | double dot = dx1 * dx2 + dy1 * dy2; 33 | double l1 = sqrt(SQR(dx1)+SQR(dy1)); 34 | double l2 = sqrt(SQR(dx2)+SQR(dy2)); 35 | 36 | return acos(dot / (l1*l2)); 37 | } 38 | 39 | int main(){ 40 | Point a, b, c; 41 | printf("Enter A, B and C:\n"); 42 | while(scanf("%lf %lf %lf %lf %lf %lf", 43 | &a.x, &a.y, &b.x, &b.y, &c.x, &c.y) == 6){ 44 | printf("Angle ABC in radians = %f\n", angle2d(a, b, c)); 45 | } 46 | return 0; 47 | } 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /graph/toposort/toposort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | // Typedefs for readability. 8 | typedef vector >::const_iterator ConstNodeIterator; 9 | typedef list::const_iterator ConstEdgeIterator; 10 | 11 | // Adjacency list graph representation. 12 | struct Graph { 13 | Graph(int N) : graph(N, list()) {} 14 | void addEdge(int src, int dst) { graph[src].push_back(dst); } 15 | vector > graph; 16 | }; 17 | 18 | // DFS-based Toposort algorithm. Visit children, then append this node. 19 | void visit(const Graph& G, int node, vector& marked, vector& tempMarked, vector& sorted) 20 | { 21 | if (tempMarked[node]) return; // Error: Not a DAG, topological sort not possible. 22 | if (marked[node]) return; // This is OK 23 | tempMarked[node] = true; 24 | for (ConstEdgeIterator it = G.graph[node].begin(); it != G.graph[node].end(); ++it) { 25 | visit(G, *it, marked, tempMarked, sorted); 26 | } 27 | tempMarked[node] = false; 28 | marked[node] = true; 29 | sorted.push_back(node); 30 | } 31 | 32 | // Topological sort. Wrapper around visit, sorts all components of graph. 33 | vector Toposort(const Graph& G) 34 | { 35 | vector sorted; 36 | sorted.reserve(G.graph.size()); 37 | vector marked(G.graph.size(), false); 38 | vector tempMarked(G.graph.size(), false); 39 | for (int i = 0; i < marked.size(); ++i) 40 | if (!marked[i]) visit(G, i, marked, tempMarked, sorted); 41 | reverse(sorted.begin(), sorted.end()); 42 | return sorted; 43 | } 44 | -------------------------------------------------------------------------------- /arithmetic/solve_quad.c: -------------------------------------------------------------------------------- 1 | /* Arithmetic: Quadratic equation solver 2 | ================================================================= 3 | Description: Finds solutions to the quadratic equation: 4 | ax^2+bx+c = 0 5 | 6 | Complexity: O(1) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Sept 8, 2002 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 1 Successful use (Sept 2002) 13 | (Spain - 10357) 14 | Notes: When there are two solutions for x, r.x[0] is not 15 | necessarily smaller than r.x[1] 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | typedef struct{ 22 | int n; /* Number of solutions */ 23 | double x[2]; /* Solutions */ 24 | } Result; 25 | 26 | Result solve_quad(double a, double b, double c){ 27 | Result r; 28 | double z = b*b-4*a*c; 29 | 30 | if(z < 0){ 31 | r.n = 0; 32 | } else if(z == 0){ 33 | r.n = 1; 34 | r.x[0] = -b/(2*a); 35 | } else { 36 | r.n = 2; 37 | r.x[0] = (-b+sqrt(z))/(2*a); 38 | r.x[1] = (-b-sqrt(z))/(2*a); 39 | } 40 | return r; 41 | } 42 | 43 | int main(){ 44 | double a,b,c; 45 | Result r; 46 | int i; 47 | 48 | while(scanf("%lf %lf %lf", &a, &b, &c) == 3){ 49 | r = solve_quad(a,b,c); 50 | printf("%d solution(s)\n", r.n); 51 | for(i = 0; i < r.n; i++){ 52 | printf("x = %f\n", r.x[i]); 53 | } 54 | } 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /2d_geometry/circ_tangents.c: -------------------------------------------------------------------------------- 1 | /* 2D Geometry: Circle tangents 2 | ================================================================= 3 | Description: Given a circle (defined by a center point and radius) 4 | and a point strictly outside the circle, returns the 5 | two points of tangency. 6 | 7 | Complexity: O(1) 8 | ----------------------------------------------------------------- 9 | Author: Ashley Zinyk 10 | Date: Nov 19, 2002 11 | References: 12 | ----------------------------------------------------------------- 13 | Reliability: 0 14 | Notes: Assumes a non-zero distance between p and c. 15 | */ 16 | 17 | #include 18 | #include 19 | #define SQR(x) ((x)*(x)) 20 | 21 | typedef struct { 22 | double x, y; 23 | } Point; 24 | 25 | double dist2(Point a, Point b) { 26 | return SQR(a.x-b.x) + SQR(a.y-b.y); 27 | } 28 | 29 | Point a, b; 30 | 31 | void circ_tangents(Point c, double r, Point p) { 32 | double perp, para, tmp = dist2(p,c); 33 | 34 | para = r*r/tmp; 35 | perp = r*sqrt(tmp-r*r)/tmp; 36 | 37 | a.x = c.x + (p.x-c.x)*para - (p.y-c.y)*perp; 38 | a.y = c.y + (p.y-c.y)*para + (p.x-c.x)*perp; 39 | b.x = c.x + (p.x-c.x)*para + (p.y-c.y)*perp; 40 | b.y = c.y + (p.y-c.y)*para - (p.x-c.x)*perp; 41 | } 42 | 43 | int main() { 44 | Point c, p; 45 | double rad; 46 | 47 | while (scanf("%lf %lf %lf", &c.x, &c.y, &rad)==3) { 48 | scanf("%lf %lf",&p.x,&p.y); 49 | circ_tangents(c, rad, p); 50 | printf("%g,%g %g,%g\n",a.x,a.y,b.x,b.y); 51 | } 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /num_theory/isprime_fast.cpp: -------------------------------------------------------------------------------- 1 | /* Author: Noah Weninger, 2018 2 | 3 | Tests if a 64-bit number is prime using the deterministic Miller-Rabin 4 | algorithm. This requires use of the __uint128_t numeric type, which is 5 | nonstandard and might not be supported by every compiler. 6 | 7 | Complexity: O(log n) with a relatively large constant 8 | 9 | Reference: 10 | https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test#Deterministic_variants_of_the_test 11 | 12 | Reliability: 13 | primes2 - Open Kattis 14 | psuedoprime - Open Kattis 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | using namespace std; 21 | 22 | using u128 = __uint128_t; 23 | u128 powmod(u128 b, u128 e, u128 m) { 24 | u128 res = 1; 25 | for (b %= m; e; e >>= 1) { 26 | if (e&1) res = res*b%m; 27 | b = b*b%m; 28 | } 29 | return res; 30 | } 31 | bool is_prime(uint64_t n) { 32 | if (n < 2) return false; 33 | u128 d = n-1, r = 0; 34 | while (d%2 == 0) r++, d /= 2; 35 | for (u128 a : {2,3,5,7,11,13,17,19,23,29,31,37}) { 36 | if (a > n-2) break; 37 | u128 x = powmod(a, d, n); 38 | if (x == 1 || x == n-1) continue; 39 | for (u128 j = 0; r && j < r-1; j++) { 40 | x = x*x%n; 41 | if (x == n-1) goto next; 42 | } 43 | return false; 44 | next:; 45 | } 46 | return true; 47 | } 48 | int main() { 49 | uint64_t n; 50 | while(cin >> n) { 51 | cout << (is_prime(n) ? "prime" : "composite") << endl; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Search/walk.c: -------------------------------------------------------------------------------- 1 | /* Search: Self Avoiding walk template 2 | ================================================================= 3 | Description: A template for a self-avoiding walk search. 4 | A self avoiding walk is one in which at each turn 5 | one walks N, E, S or W, but never visits a place 6 | he/she has visited. 7 | 8 | Complexity: O(exponential) 9 | ----------------------------------------------------------------- 10 | Author: Gilbert Lee 11 | Date: March 12, 2003 12 | References: 13 | ----------------------------------------------------------------- 14 | Reliability: 0 15 | Notes: 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #define MAXN 100 22 | 23 | int Sx[MAXN], Sy[MAXN], n, total; 24 | char walk[MAXN]; 25 | char dir[5] = "NESW"; 26 | int dx[4] = {0,1,0,-1}; 27 | int dy[4] = {1,0,-1,0}; 28 | 29 | void Walk(int pos){ 30 | int i, j; 31 | if(pos == n){ 32 | total++; 33 | walk[pos] = 0; 34 | printf("%s%c", walk, total%10 ? ' ' : '\n'); 35 | return; 36 | } 37 | for(i = 0; i < 4; i++){ 38 | Sx[pos+1] = Sx[pos]+dx[i]; 39 | Sy[pos+1] = Sy[pos]+dy[i]; 40 | walk[pos] = dir[i]; 41 | for(j = 0; j <= pos; j++) 42 | if(Sx[j] == Sx[pos+1] && Sy[j] == Sy[pos+1]) break; 43 | if(j == pos+1) Walk(pos+1); 44 | } 45 | } 46 | 47 | int main(){ 48 | while(scanf("%d", &n) == 1){ 49 | total = Sx[0] = Sy[0] = 0; 50 | Walk(0); /* Start recursive call */ 51 | printf("\nTotal # of self-avoiding walks of size %d = %d\n\n", n, total); 52 | } 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /world_finals/src/code/Graph/bellmanford_negativecycle_path.cpp: -------------------------------------------------------------------------------- 1 | const int MaxN = 205; 2 | int N; // TODO 3 | struct Edge { int from, to, cost; }; 4 | vector allEdgesFromNode[MaxN]; 5 | // MUST be updated in update loop 6 | int predecessor[MaxN]; 7 | // If the END of a path is in negative cycle, then no min cost path 8 | bool inNegativeCycle[MaxN]; 9 | // Black - No cycle. 10 | // Gray - Is in a cycle 11 | // White - unknown. 12 | const int White = 0, Gray = 1, Black = 2; 13 | int color[MaxN]; 14 | // Determines if a node is contained in an infinite cycle 15 | int ExpandPredecessor(int node) { 16 | if(color[node] != White) return color[node]; 17 | color[node] = Gray; 18 | // Not part of a cycle at all 19 | if(predecessor[node] == -1) return color[node] = Black; 20 | int newColor = ExpandPredecessor(predecessor[node]); 21 | inNegativeCycle[node] = (newColor == Gray); 22 | return color[node] = newColor; 23 | } 24 | void ExpandNegativeCycle(int node) { 25 | inNegativeCycle[node] = true; 26 | for(Edge &e: allEdgesFromNode[node]) 27 | if(!inNegativeCycle[e.to]) ExpandNegativeCycle(e.to); 28 | } 29 | void FinishUpBellmanFord() { 30 | // Go along the predecessor graph 31 | for(int i = 0; i < N; ++i) color[i] = White; 32 | // Find all nodes that are part of a negative cycle 33 | for(int i = 0; i < N; ++i) ExpandPredecessor(i); 34 | // Now, expand from all nodes that are in a negative cycle 35 | // - they cause all children to become negative cycle nodes 36 | for(int i = 0; i < N; ++i) 37 | if(inNegativeCycle[i]) ExpandNegativeCycle(i); 38 | } 39 | -------------------------------------------------------------------------------- /2d_geometry/area_heron.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Area of triangle - Heron's formula 2 | ================================================================= 3 | Description: Given the three lengths of a triangle, returns 4 | the area of the triangle. 5 | Returns -1 if triangle does not exist 6 | Complexity: O(1) (square root) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee, Ashley Zinyk 9 | Date: Sept 7, 2002 10 | References: http://mathworld.wolfram.com/Area.html 11 | ----------------------------------------------------------------- 12 | Reliability: 1 (Sept 2002) 13 | Notes: If you deal with needle-shaped triangles, you might have 14 | problems with numerical inaccuracy. In that case, try 15 | area_heron2, which is more stable but hard to type in. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | /* 22 | double area_heron2(double a, double b, double c) { 23 | double t; 24 | 25 | if (a < b) { t=a; a=b; b=t; } 26 | if (a < c) { t=a; a=c; c=t; } 27 | if (b < c) { t=b; b=c; c=t; } 28 | 29 | if ((c-(a-b)) < 0.0) return -1; 30 | return sqrt((a+(b+c))*(c-(a-b))*(c+(a-b))*(a+(b-c)))/4.0; 31 | } */ 32 | 33 | double area_heron(double a, double b, double c){ 34 | double s = (a+b+c)/2.0; 35 | if(a > s || b > s || c > s) return -1; 36 | return sqrt(s*(s-a)*(s-b)*(s-c)); 37 | } 38 | 39 | int main(){ 40 | double a, b, c; 41 | 42 | while(scanf("%lf %lf %lf", &a, &b, &c) == 3){ 43 | printf("Area of triangle = %f\n", area_heron(a,b,c)); 44 | } 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Search/color.c: -------------------------------------------------------------------------------- 1 | /* Search: Graph coloring template 2 | ================================================================= 3 | Description: Given a graph, this is a template for k-coloring 4 | it. 5 | 6 | Complexity: O(exponential) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Mar 14, 2003 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 0 13 | Notes: -The graph is given by the adjacency matrix adj[][]. 14 | -The coloring of the graph is stored in color[]; 15 | -Colors run from 0...k-1 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #define MAXN 50 22 | 23 | int adj[MAXN][MAXN], n, k, total; 24 | int color[MAXN]; 25 | 26 | void BackTrack(int pos){ 27 | int i, c; 28 | if(pos == n){ 29 | total++; 30 | printf("{"); 31 | for(i = 0; i < n; i++) 32 | printf("%d%c", color[i], i == n-1 ? '}' : ','); 33 | printf("%c", total % 5 ? ' ' : '\n'); 34 | return; 35 | } 36 | for(c = 0; c < k; c++){ 37 | for(i = 0; i < pos; i++) 38 | if(adj[i][pos] && color[i] == c) break; 39 | if(i == pos){ 40 | color[pos] = c; 41 | BackTrack(pos+1); 42 | } 43 | } 44 | } 45 | 46 | int main(){ 47 | int i, j; 48 | 49 | while(scanf("%d %d", &n, &k) == 2){ 50 | for(i = 0; i < n; i++) for(j = 0; j < n; j++) 51 | scanf("%d", &adj[i][j]); 52 | total = 0; 53 | BackTrack(0); 54 | printf("Total %d-colorings: %d\n", k, total); 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /arithmetic/simpsons.c: -------------------------------------------------------------------------------- 1 | /* Arithmatic: Simpson's Rule for Numerical Intergration 2 | ================================================================= 3 | Description: Numerical integration of the function f from a to b 4 | Splits the interval [a,b] into 2k pieces. 5 | The error is <= (b-a)/180.0 * M * h^4 6 | where: 7 | M = max( abs(f''''(x))) for x in [a,b] 8 | h = (b-a)/2k 9 | Note that this means the integrals for low degree 10 | polynomials are computed exactly 11 | 12 | Complexity: O(k) 13 | ----------------------------------------------------------------- 14 | Author: Adam Beacham, Brian Lau 15 | Date: Oct 4, 2002 16 | References: Any Calculus book. 17 | ----------------------------------------------------------------- 18 | Reliability: 0/0 19 | Notes: 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | 26 | double Simpson(double a, double b, int k, double (*f)(double)){ 27 | double dx, x, t; 28 | int i; 29 | 30 | /* assert( (a - b) != 0 && k > 0); */ 31 | 32 | dx = (b-a)/(2.0*k); 33 | t = 0; 34 | 35 | for( i=0; i 23 | #include 24 | #define EPS 1E-8 25 | #define SQR(x) ((x)*(x)) 26 | 27 | typedef struct { 28 | double x, y; 29 | } Point; 30 | 31 | Point closest_pt_lineseg(Point a, Point b, Point c) { 32 | Point p; 33 | double dp; 34 | 35 | b.x -= a.x; 36 | b.y -= a.y; 37 | if (fabs(b.x) < EPS && fabs(b.y) < EPS) return a; 38 | dp = (b.x*(c.x-a.x) + b.y*(c.y-a.y))/(SQR(b.x)+SQR(b.y)); 39 | if (dp > 1) dp = 1; 40 | if (dp < 0) dp = 0; 41 | p.x = b.x*dp + a.x; 42 | p.y = b.y*dp + a.y; 43 | return p; 44 | } 45 | 46 | int main() { 47 | Point a, b, c, d; 48 | 49 | while (scanf("%lf %lf %lf %lf %lf %lf", 50 | &a.x, &a.y, &b.x, &b.y, &c.x, &c.y)==6) { 51 | d = closest_pt_lineseg(a,b,c); 52 | printf("%g %g\n", d.x, d.y); 53 | } 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /2d_geometry/rotate_2d.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Rotation of a point around a point 2 | ================================================================= 3 | Description: Rotates a point P around an origin point O, and 4 | returns the new point. The parameter theta is the 5 | amount to rotate P counter-clockwise, and is 6 | measured in radians. 7 | 8 | Complexity: O(1) (trig functions) 9 | ----------------------------------------------------------------- 10 | Author: Gilbert Lee 11 | Date: Sept 8, 2002 12 | References: 13 | ----------------------------------------------------------------- 14 | Reliability: 2 (Spain 10406, 10250) 15 | Notes: The routine has a built in fixer for -0.00 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #define EPS 1e-8 22 | 23 | typedef struct{ 24 | double x, y; 25 | } Point; 26 | 27 | Point rotate_2d(Point p, Point o, double theta){ 28 | double m[2][2]; 29 | Point r; 30 | 31 | m[0][0] = m[1][1] = cos(theta); 32 | m[0][1] = -sin(theta); 33 | m[1][0] = -m[0][1]; 34 | p.x -= o.x; 35 | p.y -= o.y; 36 | r.x = m[0][0] * p.x + m[0][1] * p.y + o.x; 37 | r.y = m[1][0] * p.x + m[1][1] * p.y + o.y; 38 | if(fabs(r.x) < EPS) r.x = 0; 39 | if(fabs(r.y) < EPS) r.y = 0; 40 | return r; 41 | } 42 | 43 | int main(){ 44 | Point p,o,r; 45 | double deg, PI = acos(-1); 46 | 47 | while(scanf("%lf %lf %lf %lf %lf", 48 | &p.x, &p.y, &o.x, &o.y, °) == 5){ 49 | deg *= PI/180.0; 50 | r = rotate_2d(p,o,deg); 51 | printf("[%.3f,%.3f] rotated %.3f radians around [%.3f,%.3f] = [%.3f,%.3f]\n", 52 | p.x, p.y, deg, o.x, o.y, r.x, r.y); 53 | } 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /2d_geometry/midpts2vert.c: -------------------------------------------------------------------------------- 1 | /* 2D Geometry: Polygon Midpoints to Verticies 2 | ================================================================= 3 | Description: Consider a polygon with n sides. Given the 4 | midpoints of each side, this code will find the 5 | vertices of the polygon. 6 | 7 | Complexity: O(n) 8 | ----------------------------------------------------------------- 9 | Author: Ashley Zinyk 10 | Date: Nov 19, 2002 11 | References: 12 | ----------------------------------------------------------------- 13 | Reliability: 0 14 | Notes: This only works when n is odd; the answer is not 15 | unique for polygons with an even number of vertices. 16 | The polygon does not need to be convex. The points 17 | can be in clockwise or counterclockwise order. 18 | */ 19 | 20 | #include 21 | 22 | typedef struct { 23 | double x, y; 24 | } Point; 25 | 26 | void midpts2vert(Point *midpts, int n, Point *poly) { 27 | int i; 28 | 29 | poly[0] = midpts[0]; 30 | for (i = 1; i < n; i += 2) { 31 | poly[0].x += midpts[i+1].x - midpts[i].x; 32 | poly[0].y += midpts[i+1].y - midpts[i].y; 33 | } 34 | for (i = 1; i < n; i++) { 35 | poly[i].x = 2.0*midpts[i-1].x - poly[i-1].x; 36 | poly[i].y = 2.0*midpts[i-1].y - poly[i-1].y; 37 | } 38 | } 39 | 40 | int main() { 41 | Point midpts[1000], poly[1000]; 42 | int i, n; 43 | 44 | while (scanf("%d",&n)==1) { 45 | for (i = 0; i < n; i++) 46 | scanf("%lf %lf", &midpts[i].x, &midpts[i].y); 47 | midpts2vert(midpts, n, poly); 48 | for (i = 0; i < n; i++) 49 | printf("%0.3f %0.3f\n", poly[i].x, poly[i].y); 50 | } 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /world_finals/src/code/Combinatorics/(Un)Ranking of K-combination out of N.cpp: -------------------------------------------------------------------------------- 1 | const int maxn = 100; 2 | const int maxk = 10; 3 | // combination[i][j] = j!/(i!*(j-i)!) 4 | long long combination[maxk][maxn]; 5 | long long cumsum[maxk][maxn]; 6 | void initialize() { //~O(nk) 7 | memset(combination, 0, sizeof combination); 8 | for(int i = 0; i < maxn; i++) combination[0][i] = 1; 9 | for(int i = 1; i < maxk; i++) 10 | for(int j = 1; j < maxn; j++) combination[i][j] = combination[i][j - 1] + combination[i - 1][j - 1]; 11 | for(int i = 0; i < maxk; i++) cumsum[i][0] = combination[i][0]; 12 | for(int i = 0; i < maxk; i++) 13 | for(int j = 1; j < maxn; j++) cumsum[i][j] = cumsum[i][j - 1] + combination[i][j]; 14 | } 15 | // Returns rank of the given combination 'c' of n objects. 16 | long long rank_comb(int n, vector c) { 17 | long long ans = 0; 18 | int prev = -1; 19 | sort(c.begin(), c.end()); // comment this if it is sorted 20 | for(int i = 0; i < c.size(); i++) { 21 | ans += cumsum[c.size() - i - 1][n - prev - 2] - cumsum[c.size() - i - 1][n - c[i] - 1]; 22 | prev = c[i]; 23 | } 24 | return ans; 25 | } 26 | struct comp { 27 | long long base; 28 | int operator()(long long a, long long val) { return (base - a) > val; } 29 | }; 30 | // Returns k-combination of rank 'r' of n objects 31 | vector unrank_comb(int n, int k, long long r) { 32 | vector c; 33 | int prev = -1; 34 | for(int i = 0; i < k; i++) { 35 | int j = k - i - 1; 36 | long long base = cumsum[j][n - prev - 2]; 37 | prev = n - 1 - (lower_bound(cumsum[j], cumsum[j] + n - prev - 1, r, comp{base}) - cumsum[j]); 38 | r -= base - cumsum[j][n - prev - 1]; 39 | c.push_back(prev); 40 | } 41 | return c; 42 | } 43 | -------------------------------------------------------------------------------- /2d_geometry/isect_circ_area.c: -------------------------------------------------------------------------------- 1 | /* 2D Geometry - Circle Intersection Area 2 | ================================================================= 3 | Description: Computes the area of intersection of two circles 4 | Complexity: O(1) 5 | ----------------------------------------------------------------- 6 | Author: Scott Crosswhite 7 | Date: Oct 24, 2002 8 | References: http://hades.ph.tn.tudelft.nl/Internal/... 9 | .../Mathworld/math/math/c/c308.htm 10 | ----------------------------------------------------------------- 11 | Reliability: 0 12 | Notes: 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #define EPSILON 1e-8 20 | #define SQR(x) ((x)*(x)) 21 | 22 | double PI; 23 | 24 | typedef struct { 25 | double x, y; 26 | } Point; 27 | 28 | typedef struct { 29 | Point o; 30 | double r; 31 | } Circle; 32 | 33 | double CIArea (Circle A, Circle B) { 34 | double d, dA, dB, tx, ty; 35 | 36 | d = sqrt(SQR(B.o.x - A.o.x) + SQR(B.o.y - A.o.y)); 37 | 38 | if ((d < EPSILON) || (d + A.r <= B.r) || (d + B.r <= A.r)) 39 | return SQR((B.r < A.r) ? B.r : A.r) * PI; 40 | if (d >= A.r + B.r) 41 | return 0; 42 | 43 | dA = tx = (SQR(d) + SQR(A.r) - SQR(B.r))/d/2; 44 | ty = sqrt(SQR(A.r) - SQR(tx)); 45 | dB = d - dA; 46 | 47 | return SQR(A.r)*acos(dA/A.r) - dA*sqrt(SQR(A.r)-SQR(dA)) 48 | + SQR(B.r)*acos(dB/B.r) - dB*sqrt(SQR(B.r)-SQR(dB)); 49 | } 50 | 51 | int main () { 52 | Circle A, B; 53 | 54 | PI = acos(-1); 55 | 56 | while (scanf("%lf %lf %lf %lf %lf %lf", 57 | &A.o.x, &A.o.y, &A.r, &B.o.x, &B.o.y, &B.r) == 6) { 58 | printf("Area = %.5lf\n", CIArea(A, B)); 59 | } 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /data_structures/unionfind.c: -------------------------------------------------------------------------------- 1 | /* Data Structures: Unionfind with array 2 | ================================================================= 3 | Description: Unionfind is a way to implement the union operator 4 | on sets. It consists of 2 functions: 5 | getRoot(x) which returns the identifier of a set 6 | Union(a,b) which performs a union on the set 7 | containing a with the set containing b 8 | 9 | Complexity: Union - O(1) 10 | getRoot - O(roughly constant) 11 | ----------------------------------------------------------------- 12 | Author: Gilbert Lee 13 | Date: Sept 21, 2002 14 | References: 15 | ----------------------------------------------------------------- 16 | Reliability: 17 | Notes: The array sets must be initialized to -1. Negative 18 | numbers in the array represent the size of the set 19 | associated with that element, while positive numbers 20 | serve as a link back to the root of the set. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | #define MAXN 1000 27 | 28 | int sets[MAXN]; 29 | 30 | int getRoot(int x){ 31 | if(sets[x] < 0) return x; 32 | return sets[x] = getRoot(sets[x]); 33 | } 34 | 35 | void Union(int a, int b){ 36 | int ra = getRoot(a); 37 | int rb = getRoot(b); 38 | 39 | if(ra != rb){ 40 | sets[ra] += sets[rb]; 41 | sets[rb] = ra; 42 | } 43 | } 44 | 45 | int main(){ 46 | int a, b, i, n, m; 47 | 48 | while(scanf("%d %d", &n, &m) == 2){ 49 | memset(sets, -1, sizeof(sets)); 50 | for(i = 0; i < m; i++){ 51 | scanf("%d %d", &a, &b); 52 | Union(a,b); 53 | } 54 | for(i = 0; i < n; i++){ 55 | printf("%d belongs in the set with [%d]\n", i, getRoot(i)); 56 | } 57 | } 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /generators/nqueens.c: -------------------------------------------------------------------------------- 1 | /* Generators: N-Queens Solution Generator 2 | ================================================================= 3 | Description: This code generates a solution for the n-queens 4 | problem. Solutions exist for n = 1 || n > 3. 5 | Solutions are stored in the array called row[], 6 | where row[i] represents the row where the queen in 7 | the i'th column is placed. Coordinates are [0..n-1] 8 | 9 | Complexity: O(n) 10 | ----------------------------------------------------------------- 11 | Author: Gilbert Lee 12 | Date: Sept 9, 2002 13 | References: www.bridges.canterbury.ac.nz/features/eight.html 14 | ----------------------------------------------------------------- 15 | Reliability: 1 (Sept 2002) 16 | Notes: - This solution is only 1 of perhaps many 17 | solutions 18 | - No checking is done by the routine for valid n 19 | * Solves Spanish Problem 10094 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #define MAXN 10001 26 | 27 | int row[MAXN]; 28 | 29 | void gen_nqueens(int n){ 30 | int i; 31 | 32 | if(n % 2){ 33 | gen_nqueens(n-1); 34 | row[n-1] = n-1; 35 | } else { 36 | if(n % 6 == 2){ 37 | for(i = 0; i < n/2; i++) row[i] = (n/2+2*i-1)%n; 38 | for(i = n/2; i < n; i++) row[i] = (n/2+2*i+2)%n; 39 | } else { 40 | for(i = 0; i < n/2; i++) row[i] = 2*i+1; 41 | for(i = n/2; i < n; i++) row[i] = (2*i)%n; 42 | } 43 | } 44 | } 45 | 46 | int main(){ 47 | int i, n; 48 | 49 | while(scanf("%d", &n) == 1){ 50 | if(n == 1 || n > 3){ 51 | gen_nqueens(n); 52 | for(i = 0; i < n; i++) 53 | printf("%d%c", row[i], i == n-1 ? '\n' : ' '); 54 | } else { 55 | printf("Impossible\n"); 56 | } 57 | } 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /2d_geometry/centroid.c: -------------------------------------------------------------------------------- 1 | /* 2D Geometry: Centroid of a Polygon 2 | ================================================================= 3 | Description: Given a polygon as a set of N points, this code finds 4 | the centroid of the polygon. 5 | 6 | Complexity: O(N) 7 | ----------------------------------------------------------------- 8 | Author: Ashley Zinyk 9 | Date: Nov 8, 2003 10 | References: http://www.netcomuk.co.uk/~jenolive/centroid.html 11 | www.exaflop.org/docs/cgafaq/cga2.html 12 | see also area_poly.c 13 | ----------------------------------------------------------------- 14 | Reliability: 2 (Spain 10002) 15 | (Center of Mass Nov 2003) 16 | Notes: Points must be in clockwise or counterclockwise order. 17 | The area of the polygon must be non-zero. 18 | The polygon must not be self-intersecting (simple) 19 | The polygon may or may not be convex. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | typedef struct { 26 | double x, y; 27 | } Point; 28 | 29 | Point centroid(Point *p, int n) { 30 | double area, sum; 31 | Point c; 32 | int i, j; 33 | 34 | c.x = c.y = sum = 0.0; 35 | for(i = n-1, j = 0; j < n; i = j++) { 36 | sum += area = p[i].x * p[j].y - p[i].y * p[j].x; 37 | c.x += (p[i].x + p[j].x)*area; 38 | c.y += (p[i].y + p[j].y)*area; 39 | } 40 | sum *= 3.0; 41 | c.x /= sum; 42 | c.y /= sum; 43 | return c; 44 | } 45 | 46 | int main() { 47 | Point poly[100], c; 48 | int i, n; 49 | 50 | while (scanf("%d",&n)==1) { 51 | if (n < 3) break; 52 | for (i = 0; i < n; i++) 53 | scanf("%lf %lf",&poly[i].x, &poly[i].y); 54 | c = centroid(poly,n); 55 | printf("%0.3f %0.3f\n",c.x,c.y); 56 | } 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /data_structures/heap/heap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | // Templatized Heap (see test.cpp for usage) 8 | // Heap is a min-heap (smallest element on top) 9 | // Heap elements are stored in a vector. 10 | // __heap[2*i+1] and __heap[2*i+2] are the children of __heap[i] 11 | template 12 | class Heap { 13 | public: 14 | virtual ~Heap() {} 15 | virtual void Reserve(int N) { _heap.reserve(N); } 16 | virtual void Insert(const T& elem) 17 | { 18 | _heap.push_back(elem); 19 | ShiftUp(_heap.size()-1); 20 | 21 | } 22 | virtual T Top() const { return _heap[0]; } 23 | virtual void Pop() 24 | { 25 | swap(_heap[0], _heap[_heap.size()-1]); 26 | _heap.pop_back(); 27 | ShiftDown(0); 28 | } 29 | virtual void Heapify(const vector& vect) 30 | { 31 | _heap = vect; 32 | for (int i = Parent(_heap.size()-1); i >= 0; --i) 33 | ShiftDown(i); 34 | } 35 | virtual int Size() const { return _heap.size(); } 36 | private: 37 | virtual int Parent(int i) const { return (i-1)/2; } 38 | virtual int LeftChild(int i) const { return 2*i+1; } 39 | virtual int RightChild(int i) const { return 2*i+2; } 40 | virtual void ShiftUp(int i) 41 | { 42 | for (; i > 0 && _heap[Parent(i)] > _heap[i]; i = Parent(i)) 43 | swap(_heap[Parent(i)], _heap[i]); 44 | } 45 | virtual void ShiftDown(int i) 46 | { 47 | int minIndex; 48 | while (true) { 49 | minIndex = LeftChild(i); 50 | if (minIndex >= _heap.size()) break; 51 | if (RightChild(i) < _heap.size() && _heap[RightChild(i)] < _heap[LeftChild(i)]) minIndex = RightChild(i); 52 | if (_heap[minIndex] < _heap[i]) { 53 | swap(_heap[i], _heap[minIndex]); 54 | i = minIndex; 55 | } else { 56 | break; 57 | } 58 | } 59 | } 60 | vector _heap; 61 | }; 62 | -------------------------------------------------------------------------------- /num_theory/factinfact.c: -------------------------------------------------------------------------------- 1 | /* Number Theory: Factors in Factorial 2 | ================================================================= 3 | Description: How many factors of k are there in n! (n factorial)? 4 | 5 | Complexity: O(lg(n)) if k is prime 6 | O(n) to generate primes in general case 7 | ----------------------------------------------------------------- 8 | Author: Ashley Zinyk 9 | Date: February 11, 2003 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 3 (Spain 160, 568, 10061) 13 | Notes: If k is guaranteed prime, just use pfif(). 14 | It only makes sense when k >= 2, n >= 0. 15 | */ 16 | 17 | #include 18 | 19 | int pfif(int k, int n) { 20 | int pow, sum = 0; 21 | 22 | for (pow = k; pow <= n; pow *= k) 23 | sum += n / pow; 24 | return sum; 25 | } 26 | 27 | int primes[4800]; 28 | 29 | void getPrimes(){ 30 | int i, j, isprime, psize = 1; 31 | 32 | primes[0] = 2; 33 | for(i = 3; i <= 46340; i+= 2){ 34 | for(isprime = j = 1; j < psize; j++){ 35 | if(i % primes[j] == 0){ 36 | isprime = 0; 37 | break; 38 | } 39 | if(1.0*primes[j]*primes[j] > i) break; 40 | } 41 | if(isprime) primes[psize++] = i; 42 | } 43 | } 44 | 45 | int fif(int k, int n) { 46 | int i, p, m, tmp, min = 2000000000; 47 | 48 | for (i = 0; k > 1; i++) { 49 | p = primes[i]; 50 | if (p*p > k) p = k; 51 | for (m = 0; k % p == 0; m++) k /= p; 52 | if (!m) continue; 53 | tmp = pfif(p,n)/m; 54 | if (tmp < min) min = tmp; 55 | } 56 | return min; 57 | } 58 | 59 | int main() { 60 | int n, k; 61 | 62 | getPrimes(); 63 | while (scanf("%d %d",&n, &k)==2) 64 | printf("There's %d factor(s) of %d in %d!\n",fif(k,n),k,n); 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /num_theory/modular_inverse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Compute the modular inverse of a number. 3 | 4 | Author: Zac Friggstad 5 | 6 | Given an integer a and an integer m >= 0, either finds an integer b with 7 | m | (a*b - 1) (i.e. a*b == 1 mod m) or determines there is no such integer. 8 | 9 | Returns b in the range 1 <= b <= m if there was a solution 10 | Otherwise returns -1 11 | 12 | Running time: O(log(a) + log(m)) 13 | 14 | Reliability: Candy Distribution from GCPC 2012 (be careful when k = 1) 15 | */ 16 | 17 | #include 18 | 19 | using namespace std; 20 | 21 | // the same one from gcd_ex.cpp 22 | int gcd_ex(int a, int b, int& s, int& t) { 23 | int r0 = a, r1 = b, q; 24 | int s0 = 1, s1 = 0; 25 | int t0 = 0, t1 = 1; 26 | 27 | //invariant: ri = a*si + b*ti for both i = 0 and i = 1 28 | while (r1) { 29 | q = r0 / r1; 30 | 31 | r0 -= q*r1; 32 | swap(r0, r1); 33 | 34 | s0 -= q*s1; 35 | swap(s0, s1); 36 | 37 | t0 -= q*t1; 38 | swap(t0, t1); 39 | } 40 | 41 | //now r0 = gcd(a, b) 42 | s = s0; 43 | t = t0; 44 | 45 | return r0; 46 | } 47 | 48 | int mod_inverse(int a, int m) { 49 | int s, t; 50 | 51 | a %= m; 52 | 53 | /* can ignore the next line a is never nonnegative 54 | The current standard ensures that if m > 0 and a < 0 then 55 | a%m wiint be the negative number r closes to 0 such that m | (a-r). 56 | example: (-22) % 6 == -4 57 | 58 | http://en.cppreference.com/w/cpp/language/operator_arithmetic 59 | http://en.cppreference.com/w/cpp/numeric/math/div 60 | */ 61 | if (a < 0) a += m; 62 | 63 | if (gcd_ex(a, m, s, t) > 1) return -1; 64 | 65 | s %= m; 66 | 67 | //must always have this one, even if a > 0 is guaranteed 68 | if (s < 0) s += m; 69 | 70 | return s; 71 | } 72 | -------------------------------------------------------------------------------- /2d_geometry/pts2_genline.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Generalized Equation of a line given two points 2 | ================================================================= 3 | Description: Given two points, computes the unique values 4 | A, B and C for the line going through A and B such 5 | that Ax + By = C 6 | and A >= 0 7 | and A^2 + B^2 = 1 8 | 9 | Complexity: O(1) 10 | ----------------------------------------------------------------- 11 | Author: Gilbert Lee 12 | Date: March 7, 2003 13 | References: www.uwm.edu/~ericskey/TANOTES/Ageometry/node4.html 14 | ----------------------------------------------------------------- 15 | Reliability: 0 16 | Notes: - The good thing about a generalized equation is 17 | that unlike the slope/offset version, it is 18 | always defined 19 | - Two lines are parallel iff both their A's are the 20 | same, and their B's are the same. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | #define SQR(x) ((x)*(x)) 27 | 28 | typedef struct{ 29 | double x, y; 30 | } Point; 31 | 32 | typedef struct{ 33 | double a, b, c; 34 | } Line; 35 | 36 | Line pt2line(Point a, Point b){ 37 | double dx = a.x-b.x, dy = a.y-b.y; 38 | double len = sqrt(SQR(dx)+SQR(dy)); 39 | Line res; 40 | 41 | if(dy < 0){ 42 | dy *= -1; 43 | dx *= -1; 44 | } 45 | res.a = dy/len; 46 | res.b = -dx/len; 47 | res.c = res.a*a.x + res.b*a.y; 48 | return res; 49 | } 50 | 51 | int main(){ 52 | Point a, b; 53 | Line line; 54 | while(scanf("%lf %lf %lf %lf", &a.x, &a.y, &b.x, &b.y) == 4){ 55 | line = pt2line(a,b); 56 | printf("Equation of line going through (%.3f,%.3f)->(%.3f,%.3f):\n", 57 | a.x, a.y, b.x, b.y); 58 | printf("(%.3f) X + (%.3f) Y = %.3f\n", 59 | line.a, line.b, line.c); 60 | } 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /arithmetic/solve_cubic.c: -------------------------------------------------------------------------------- 1 | /* Arithmetic: Cubic equation solver 2 | ================================================================= 3 | Description: Finds solutions to the cubic equation: 4 | ax^3+bx^2+cx+d = 0 5 | 6 | Complexity: O(1) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Sept 8, 2002 10 | References: www.snippets.org/snippets/portable/CUBIC+C.php3 11 | ----------------------------------------------------------------- 12 | Reliability: 0 13 | Notes: 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | typedef struct{ 20 | int n; /* Number of solutions */ 21 | double x[3]; /* Solutions */ 22 | } Result; 23 | 24 | double PI; 25 | 26 | Result solve_cubic(double a, double b, double c, double d){ 27 | Result s; 28 | long double a1 = b/a, a2 = c/a, a3 = d/a; 29 | long double q = (a1*a1 - 3*a2)/9.0, sq = -2*sqrt(q); 30 | long double r = (2*a1*a1*a1 - 9*a1*a2 + 27*a3)/54.0; 31 | double z = r*r-q*q*q; 32 | double theta; 33 | 34 | if(z <= 0){ 35 | s.n = 3; 36 | theta = acos(r/sqrt(q*q*q)); 37 | s.x[0] = sq*cos(theta/3.0) - a1/3.0; 38 | s.x[1] = sq*cos((theta+2.0*PI)/3.0) - a1/3.0; 39 | s.x[2] = sq*cos((theta+4.0*PI)/3.0) - a1/3.0; 40 | } else { 41 | s.n = 1; 42 | s.x[0] = pow(sqrt(z)+fabs(r),1/3.0); 43 | s.x[0] += q/s.x[0]; 44 | s.x[0] *= (r < 0) ? 1 : -1; 45 | s.x[0] -= a1/3.0; 46 | } 47 | return s; 48 | } 49 | 50 | int main(){ 51 | double a,b,c,d; 52 | Result r; 53 | int i; 54 | 55 | PI = acos(-1); 56 | while(scanf("%lf %lf %lf %lf", &a, &b, &c, &d) == 4){ 57 | r = solve_cubic(a,b,c,d); 58 | printf("%d solution(s)\n", r.n); 59 | for(i = 0; i < r.n; i++){ 60 | printf("x = %f\n", r.x[i]); 61 | } 62 | } 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /combinatorics/digit_count.c: -------------------------------------------------------------------------------- 1 | /* Combinatorics: Digit Occurence count 2 | ================================================================= 3 | Description: Given a digit and a number N, return the number of 4 | times the digit occurs from 1..N. 5 | 6 | Complexity: O(lg N) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: May 22, 2002 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 0 13 | Notes: 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | long long digit_count(int digit, int max){ 21 | long long res = 0; 22 | char buff[15]; 23 | int i, count; 24 | 25 | if(max <= 0) return 0; 26 | 27 | /* Number of times "digit" occurs in the one's place */ 28 | res += max/10 + ((max % 10) >= digit ? 1 : 0); 29 | 30 | /* Since we start from 1, if digit = 0, remove 1 since "0" 31 | doesn't count */ 32 | if(digit == 0) res--; 33 | 34 | /* Get the number of occurences in max/10-1, and multiply this by 35 | 10 since we can choose 10 possible last digits [0-9] */ 36 | res += digit_count(digit, max/10 - 1) * 10; 37 | 38 | /* The number of occurences in max/10 is equal to (1+max%10) * the 39 | number of times "digit" occurs in max/10 */ 40 | sprintf(buff, "%d", max/10); 41 | for(i = 0, count = 0; i < strlen(buff); i++) 42 | if(buff[i] == digit+'0') count++; 43 | 44 | res += (1 + max%10) * count; 45 | return res; 46 | } 47 | 48 | int main(){ 49 | int digit, max; 50 | 51 | while(1){ 52 | printf("Enter a digit and a number: "); 53 | scanf("%d %d", &digit, &max); 54 | printf("The number of times '%d' occurs from 1..%d = %lld\n", 55 | digit, max, digit_count(digit, max)); 56 | } 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /dynamic/integer_partition.c: -------------------------------------------------------------------------------- 1 | /* Dynamic Programming: Integer Parititoning 2 | ================================================================= 3 | Description: Template for calculating the number of ways of 4 | partitioning the integer N into M parts. 5 | 6 | Complexity: O(N^2) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert LEe 9 | Date: Feb 10, 2003 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 1 (Spain 10313 Pay the Price) 13 | Notes: A partition of a number N is a representation of 14 | N as the sum of positive integers 15 | e.g. 5 = 1+1+1+1+1 16 | 17 | The number of ways of partitioning an integer N 18 | into M parts is equal to the number of ways of 19 | partitioning the number N with the largest element 20 | being of size M. This is best seen with a Ferres- 21 | Young diagram: 22 | Suppose N = 8, M = 3: 23 | 24 | 4 = * * * * 25 | 3 = * * * 26 | 1 = * 27 | 3 2 2 1 28 | By transposition from rows to columns, this equality 29 | can be seen. 30 | 31 | P(N, M) = P(N-1, M-1) + P(N-M, M) 32 | P(0, M) = P(N, 0) = 0 33 | P(N, 1) = 1 34 | */ 35 | 36 | #include 37 | #include 38 | #define MAXN 300 39 | #define ULL unsigned long long 40 | 41 | ULL A[MAXN+1][MAXN+1]; 42 | 43 | void Build(){ 44 | int i, j; 45 | 46 | memset(A, 0, sizeof(A)); 47 | A[0][0] = 1; 48 | for(i = 1; i <= MAXN; i++){ 49 | A[i][1] = 1; 50 | for(j = 2; j <= i; j++) 51 | A[i][j] = A[i-1][j-1] + A[i-j][j]; 52 | } 53 | } 54 | 55 | int main(){ 56 | int n, m; 57 | 58 | Build(); 59 | while(scanf("%d %d", &n, &m) == 2){ 60 | printf("Partitions of %d into %d parts: %llu\n", n, m, A[n][m]); 61 | } 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /2d_geometry/circ_3pts.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Parameter of circle from 3 points 2 | ================================================================= 3 | Description: This routine computes the parameters of a circle 4 | (center and radius) from 3 points. 5 | Returns non-zero if successful, zero if the three 6 | points are collinear 7 | 8 | Complexity: O(1) 9 | ----------------------------------------------------------------- 10 | Author: Howard Cheng 11 | Date: Nov 13, 2002 12 | References: www.exaflop.org/docs/cgafaq/ 13 | ----------------------------------------------------------------- 14 | Reliability: 0 15 | Notes: 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | /* how close to call equal */ 23 | #define EPS 1E-8 24 | 25 | typedef struct { 26 | double x, y; 27 | } Point; 28 | 29 | int circle(Point p1, Point p2, Point p3, Point *center, double *r) 30 | { 31 | double a,b,c,d,e,f,g; 32 | 33 | a = p2.x - p1.x; b = p2.y - p1.y; 34 | c = p3.x - p1.x; d = p3.y - p1.y; 35 | e = a*(p1.x + p2.x) + b*(p1.y + p2.y); 36 | f = c*(p1.x + p3.x) + d*(p1.y + p3.y); 37 | g = 2.0*(a*(p3.y - p2.y) - b*(p3.x - p2.x)); 38 | if (fabs(g) < EPS) return 0; 39 | center->x = (d*e - b*f) / g; 40 | center->y = (a*f - c*e) / g; 41 | *r = sqrt((p1.x-center->x)*(p1.x-center->x) + 42 | (p1.y-center->y)*(p1.y-center->y)); 43 | return 1; 44 | } 45 | 46 | int main(void) 47 | { 48 | Point a, b, c, center; 49 | double r; 50 | 51 | while (scanf("%lf %lf %lf %lf %lf %lf", 52 | &a.x, &a.y, &b.x, &b.y, &c.x, &c.y) == 6) { 53 | if (circle(a, b, c, ¢er, &r)) { 54 | printf("center = (%5.3f, %5.3f)\n", center.x, center.y); 55 | printf("radius = %5.3f\n", r); 56 | printf("\n"); 57 | } else { 58 | printf("colinear\n\n"); 59 | } 60 | } 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /arithmetic/discrete_log.cc: -------------------------------------------------------------------------------- 1 | /* Arithmetic: Discrete Logarithm solver 2 | ================================================================= 3 | Description: Given prime P, B, and N, finds the smallest 4 | exponent L such that B^L == N (mod P) 5 | 6 | Complexity: O(sqrt(P)) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Sept 13, 2002 10 | References: http://plg.uwaterloo.ca/~acm00/020126/data/B.cpp 11 | ----------------------------------------------------------------- 12 | Reliability: 1 successful use (Spain Problem 10225) Sept 2002 13 | Notes: The function either returns the exponent L, or 14 | -1 if no solution is found 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | using namespace std; 22 | 23 | #define UI unsigned 24 | #define UL unsigned long 25 | #define ULL unsigned long long 26 | 27 | map M; 28 | 29 | UL times (UL a, UL b, UL m){ 30 | return (ULL) a * b % m; 31 | } 32 | 33 | UL power(UL val, UL power, UL m){ 34 | UL res = 1, p; 35 | 36 | for(p = power; p; p=p>>1){ 37 | if(p & 1) res = times(res, val, m); 38 | val = times(val, val, m); 39 | } 40 | return res; 41 | } 42 | 43 | int discrete_log(UI p, UI b, UI n){ 44 | UL i, j, jump; 45 | 46 | M.clear(); 47 | jump = (int)sqrt(p); 48 | for (i = 0; i < jump && i < p-1; i++){ 49 | M[power(b,i,p)] = i+1; 50 | } 51 | for (i = 0; i < p-1; i+= jump){ 52 | if (j = M[times(n,power(b,p-1-i,p),p)]) { 53 | j--; 54 | return (i+j)%(p-1); 55 | } 56 | } 57 | return -1; 58 | } 59 | 60 | int main(){ 61 | UI p, b, n; 62 | int x; 63 | 64 | while(scanf("%d %d %d", &p, &b, &n) == 3){ 65 | x = discrete_log(p,b,n); 66 | if(x < 0) printf("no solution\n"); 67 | else printf("%d\n", x); 68 | } 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /3d_geometry/area_cpoly3d.c: -------------------------------------------------------------------------------- 1 | /* 3D-Geometry: Area of a convex polygon in a plane given in 3D 2 | ================================================================= 3 | Description: Given the points of a planar convex polygon in 3D 4 | space, returns its area. 5 | 6 | The points of the polygon must be either in cw or 7 | ccw order. 8 | 9 | Complexity: O(N) where N is the number of points 10 | ----------------------------------------------------------------- 11 | Author: Gilbert Lee 12 | Date: March 06, 2003 13 | References: 14 | ----------------------------------------------------------------- 15 | Reliability: 1 - Topcoder Round 2 2003 16 | Notes: - Uses Heron's formula v1. Change to v2 if needed 17 | - There must be at least 3 points 18 | - Doesn't work for non-convex polygons 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #define SQR(x) ((x)*(x)) 26 | 27 | typedef struct{ 28 | double x, y, z; 29 | } Point; 30 | 31 | double area_heron(double a, double b, double c){ 32 | double s = (a+b+c)/2.0; 33 | if(a > s || b > s || c > s) return -1; 34 | return sqrt(s*(s-a)*(s-b)*(s-c)); 35 | } 36 | 37 | double dist3d(Point a, Point b){ 38 | return sqrt(SQR(a.x-b.x)+SQR(a.y-b.y)+SQR(a.z-b.z)); 39 | } 40 | 41 | double area_poly3d(Point *p, int n){ 42 | int i; double total = 0; 43 | for(i = 2; i < n; i++) 44 | total += area_heron(dist3d(p[0], p[i]), 45 | dist3d(p[0], p[i-1]), 46 | dist3d(p[i], p[i-1])); 47 | return total; 48 | } 49 | 50 | int main(){ 51 | int i, n; Point *p; 52 | 53 | while(scanf("%d", &n) == 1 && n >= 3){ 54 | p = (Point *)malloc(n*sizeof(Point)); 55 | for(i = 0; i < n; i++) 56 | scanf("%lf %lf %lf", &p[i].x, &p[i].y, &p[i].z); 57 | printf("Area of convex polygon is %.3f\n", area_poly3d(p, n)); 58 | free(p); 59 | } 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /2d_geometry/pt_in_poly.c: -------------------------------------------------------------------------------- 1 | /* 2D Geometry: Point in Polygon Test 2 | ================================================================= 3 | Description: Determines if a point is strictly inside, outside, 4 | or on the boundary of a simple polygon. 5 | 6 | Complexity: O(N) 7 | ----------------------------------------------------------------- 8 | Author: Ashley Zinyk 9 | Date: March 12, 2003 10 | References: This is more or less taken from Randolph Franklin's 11 | http://www.ecse.rpi.edu/Homepages/wrf/geom/pnpoly.html 12 | ----------------------------------------------------------------- 13 | Reliability: 1 (Spain 634) 14 | Notes: If your points are guaranteed not to be on the 15 | boundary, remove that check. You could also return 16 | a third value, neither 0 nor 1, for boundary cases. 17 | */ 18 | 19 | #include 20 | #include 21 | #define BOUNDARY 1 22 | #define EPS 1E-8 23 | #define SQR(x) ((x)*(x)) 24 | 25 | typedef struct { 26 | double x, y; 27 | } Point; 28 | 29 | double dist2d(Point a, Point b) { 30 | return sqrt(SQR(a.x-b.x) + SQR(a.y-b.y)); 31 | } 32 | 33 | int pt_in_poly(Point *p, int n, Point a) { 34 | int i, j, c = 0; 35 | 36 | for (i = 0, j = n-1; i < n; j = i++) { 37 | if (dist2d(p[i],a)+dist2d(p[j],a)-dist2d(p[i],p[j]) < EPS) 38 | return BOUNDARY; 39 | if ((((p[i].y<=a.y) && (a.yv in the 15 | the graph, u comes before v in the ordering. 16 | 17 | There may be more than one way to topological sort 18 | a DAG. If the lexicographically first one is needed, 19 | it may be a good idea to use a priority queue instead 20 | and just pull off vertices with 0 in-degree 21 | 22 | Vertices are numbered 0..N-1. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | using namespace std; 29 | 30 | #define MAXN 1000 31 | 32 | vector g[MAXN]; 33 | int id, top[MAXN], seen[MAXN]; 34 | 35 | void DFS(int x){ 36 | seen[x] = 1; 37 | for(size_t i = 0; i < g[x].size(); i++) 38 | if(!seen[g[x][i]]) DFS(g[x][i]); 39 | top[id--] = x; 40 | } 41 | 42 | void top_sort(int n){ 43 | memset(seen, 0, sizeof(seen)); 44 | id = n-1; 45 | for(int i = 0; i < n; i++) 46 | if(!seen[i]) DFS(i); 47 | } 48 | 49 | int main(){ 50 | int n, m, i, x, y; 51 | 52 | /* n = # of vertices, m = # of edges */ 53 | while(scanf("%d %d", &n, &m) == 2){ 54 | for(i = 0; i < n; i++) g[i].clear(); 55 | for(i = 0; i < m; i++){ 56 | scanf("%d %d", &x, &y); 57 | g[x].push_back(y); 58 | } 59 | top_sort(n); 60 | for(i = 0; i < n; i++) 61 | printf("%d ", top[i]); 62 | printf("\n"); 63 | } 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /graph/floyd.c: -------------------------------------------------------------------------------- 1 | /* Graph Theory: Floyd's Algorithm - All pairs shortest path 2 | ================================================================= 3 | Description: Given a graph stored in an adjacency matrix, returns 4 | the shortest distance from node i to node j in 5 | d[i][j]. Weights of each edge must be nonnegative, 6 | and -1 is used to indicate an empty edge 7 | 8 | Complexity: O(N^3) 9 | ----------------------------------------------------------------- 10 | Author: Gilbert Lee 11 | Date: Sept 17, 2002 12 | References: 13 | ----------------------------------------------------------------- 14 | Reliability: 1 Successful use (Sept 2002) 15 | (Spain Problem 10354) 16 | Notes: Costs may be changed to doubles, but then elements 17 | need to be initialized individually (commented out 18 | below). 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | #define MAXN 101 25 | #define CType int 26 | 27 | CType g[MAXN][MAXN], dist[MAXN][MAXN]; 28 | 29 | void floyd(int n){ 30 | int i, j, k; 31 | 32 | memcpy(dist, g, sizeof(g)); 33 | for(k = 0; k < n; k++) for(i = 0; i < n; i++) for(j = 0; j < n; j++){ 34 | if(dist[i][k] != -1 && dist[k][j] != -1){ 35 | CType temp = dist[i][k] + dist[k][j]; 36 | if(dist[i][j] == -1 || dist[i][j] > temp) 37 | dist[i][j] = temp; 38 | } 39 | } 40 | for(i = 0; i < n; i++) dist[i][i] = 0; 41 | } 42 | 43 | int main(){ 44 | int i, j, n; 45 | CType w; 46 | 47 | scanf("%d", &n); 48 | 49 | /* Clear graph */ 50 | memset(g, -1, sizeof(g)); 51 | 52 | /* If using doubles: 53 | for(i = 0; i < n; i++) for(j = 0; j < n; j++) g[i][j] = -1; 54 | */ 55 | 56 | /* Read graph */ 57 | while(scanf("%d %d %d", &i, &j, &w) == 3){ 58 | g[i][j] = g[j][i] = w; 59 | } 60 | 61 | floyd(n); 62 | 63 | while(scanf("%d %d", &i, &j) == 2){ 64 | printf("%d %d: %d\n", i, j, dist[i][j]); 65 | } 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /Search/golden.c: -------------------------------------------------------------------------------- 1 | /* Search: Golden section Search 2 | ================================================================= 3 | Description: Given an function f(x) with a single local minimum, 4 | a lower and upper bound on x, and a tolerance for 5 | convergence, this function finds the value of x 6 | 7 | The function is written globally as f(x) 8 | 9 | Complexity: Depends on tolerance 10 | ----------------------------------------------------------------- 11 | Author: Gilbert Lee 12 | Date: Mar 14, 2003 13 | References: www.chemeng.ed.ac.uk/~jwp/MSO/section5/maths/ 14 | part3/handout2/ 15 | ----------------------------------------------------------------- 16 | Reliability: 0 17 | Notes: - watch out for -0.000 18 | */ 19 | 20 | #include 21 | 22 | #define GOLD 0.381966 23 | #define move(a,b,c) x[a]=x[b];x[b]=x[c];fx[a]=fx[b];fx[b]=fx[c] 24 | 25 | double f(double x){ 26 | return x*x; 27 | } 28 | 29 | double golden(double xlow, double xhigh, double tol){ 30 | double x[4], fx[4], L; 31 | int iter = 0, left = 0, mini, i; 32 | 33 | fx[0] = f(x[0]=xlow); 34 | fx[3] = f(x[3]=xhigh); 35 | 36 | while(1){ 37 | L = x[3]-x[0]; 38 | if(!iter || left){ 39 | x[1] = x[0]+GOLD*L; 40 | fx[1] = f(x[1]); 41 | } 42 | if(!iter || !left){ 43 | x[2] = x[3]-GOLD*L; 44 | fx[2] = f(x[2]); 45 | } 46 | for(mini = 0, i = 1; i < 4; i++) 47 | if(fx[i] < fx[mini]) mini = i; 48 | if(L < tol) break; 49 | 50 | if(mini < 2){ 51 | left = 1; 52 | move(3,2,1); 53 | } else { 54 | left = 0; 55 | move(0,1,2); 56 | } 57 | iter++; 58 | } 59 | return x[mini]; 60 | } 61 | 62 | int main(){ 63 | double low, high , tol, minx; 64 | 65 | while(scanf("%lf %lf %lf", &low, &high, &tol) == 3){ 66 | minx = golden(low, high, tol); 67 | printf("f(%.6f) = %.6f\n", minx, f(minx)); 68 | } 69 | return 0; 70 | } 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /world_finals/src/code/Graph/Cut edges and 2-edge-connected components.cpp: -------------------------------------------------------------------------------- 1 | // input (zero based): 2 | // g[n] should be the adjacency list of the graph 3 | // g[i] is a vector of int 4 | // output of cut_edge(): 5 | // cut_edges is a vector of pair 6 | // comp[comp_size] contains the 2 connected components 7 | // comp[i] is a vector of int 8 | const int maxn = 1000; 9 | typedef pair edge; 10 | vector g[maxn]; 11 | int n, mark[maxn], d[maxn], jad[maxn]; 12 | vector cut_edges; 13 | // for components only 14 | vector comp[maxn]; 15 | int comp_size; 16 | vector comp_stack; 17 | void dfs(int x, int level) { 18 | mark[x] = 1; 19 | // for components only 20 | comp_stack.push_back(x); 21 | int t = 0; 22 | for(int u: g[x]) { 23 | if(!mark[u]) { 24 | jad[u] = d[u] = d[x] + 1; 25 | dfs(u, level + 1); 26 | jad[x] = std::min(jad[u], jad[x]); 27 | if(jad[u] == d[u]) { 28 | cut_edges.push_back(edge(u, x)); 29 | // for components only 30 | while(comp_stack.back() != u) { 31 | comp[comp_size].push_back(comp_stack.back()); 32 | comp_stack.pop_back(); 33 | } 34 | comp[comp_size++].push_back(u); 35 | comp_stack.pop_back(); 36 | // 37 | } 38 | } else { 39 | if(d[u] == d[x] - 1) t++; 40 | if(d[u] != d[x] - 1 || t != 1) jad[x] = std::min(d[u], jad[x]); 41 | } 42 | } 43 | // for components only 44 | if(level == 0) { 45 | while(comp_stack.size() > 0) { 46 | comp[comp_size].push_back(comp_stack.back()); 47 | comp_stack.pop_back(); 48 | } 49 | comp_size++; 50 | } 51 | } 52 | void cut_edge() { 53 | memset(mark, 0, sizeof mark); 54 | memset(d, 0, sizeof d); 55 | memset(jad, 0, sizeof jad); 56 | cut_edges.clear(); 57 | // for components only 58 | for(int i = 0; i < maxn; i++) comp[i].clear(); 59 | comp_stack.clear(); 60 | comp_size = 0; 61 | for(int i = 0; i < n; i++) 62 | if(!mark[i]) dfs(i, 0); 63 | } 64 | -------------------------------------------------------------------------------- /world_finals/src/code/Graph/2-Sat and strongly connected component.cpp: -------------------------------------------------------------------------------- 1 | // Vertices are numbered 0..n-1 for true states. 2 | // False state of the variable i is i+n (i.e. other(i)) 3 | // For SCC 'n', 'adj' and 'adjrev' need to be filled. 4 | // For 2-Sat set 'n' and use add_edge 5 | // 0<=val[i]<=1 is the value for binary variable i in 2-Sat 6 | // 0<=group[i]<2*n is the scc number of vertex i. 7 | const int maxn = 1000; 8 | int n; 9 | vector adj[maxn * 2]; 10 | vector adjrev[maxn * 2]; 11 | int val[maxn]; 12 | int marker, dfst, dfstime[maxn * 2], dfsorder[maxn * 2]; 13 | int group[maxn * 2]; 14 | // For 2SAT Only 15 | inline int other(int v) { return v < n ? v + n : v - n; } 16 | inline int var(int v) { return v < n ? v : v - n; } 17 | inline int type(int v) { return v < n ? 1 : 0; } 18 | void satclear() { 19 | for(int i = 0; i < maxn + maxn; i++) { 20 | adj[i].resize(0); 21 | adjrev[i].resize(0); 22 | } 23 | } 24 | void dfs(int v) { 25 | if(dfstime[v] != -1) return; 26 | dfstime[v] = -2; 27 | int deg = adjrev[v].size(); 28 | for(int i = 0; i < deg; i++) dfs(adjrev[v][i]); 29 | dfstime[v] = dfst++; 30 | } 31 | void dfsn(int v) { 32 | if(group[v] != -1) return; 33 | group[v] = marker; 34 | int deg = adj[v].size(); 35 | for(int i = 0; i < deg; i++) dfsn(adj[v][i]); 36 | } 37 | // For 2SAT Only 38 | void add_edge(int a, int b) { 39 | adj[other(a)].push_back(b); 40 | adjrev[b].push_back(other(a)); 41 | adj[other(b)].push_back(a); 42 | adjrev[a].push_back(other(b)); 43 | } 44 | bool solve() { 45 | dfst = 0; 46 | memset(dfstime, -1, sizeof dfstime); 47 | for(int i = 0; i < n + n; i++) dfs(i); 48 | memset(val, -1, sizeof val); 49 | for(int i = 0; i < n + n; i++) dfsorder[n + n - dfstime[i] - 1] = i; 50 | memset(group, -1, sizeof group); 51 | for(int i = 0; i < n + n; i++) { 52 | marker = i; 53 | dfsn(dfsorder[i]); 54 | } 55 | // For 2SAT Only 56 | for(int i = 0; i < n; i++) { 57 | if(group[i] == group[i + n]) return 0; 58 | val[i] = (group[i] > group[i + n]) ? 0 : 1; 59 | } 60 | return 1; 61 | } 62 | -------------------------------------------------------------------------------- /c++/string_tokenizer.cc: -------------------------------------------------------------------------------- 1 | /* C++ - String Tokenizer 2 | ================================================================= 3 | Description: Takes a string and divides it into either substrings 4 | or ints 5 | Complexity: O(M) - M the length of the string 6 | ----------------------------------------------------------------- 7 | Author: Scott Crosswhite 8 | Date: Feb 10, 2003 9 | References: 10 | ----------------------------------------------------------------- 11 | Reliability: 0 12 | Notes: 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | using namespace std; 20 | 21 | /* Subdivide it into strings separated by the characters in div */ 22 | vector makeStringTokens (string s, string div) { 23 | vector items; 24 | int i=0, j; 25 | 26 | for (i=s.find_first_not_of(div, i); i!=-1; i=s.find_first_not_of(div, i=j)) { 27 | j = s.find_first_of(div, i); 28 | items.push_back(s.substr(i, j-i)); 29 | } 30 | return items; 31 | } 32 | 33 | /* Subdivide it into ints separated by the characters in div */ 34 | vector makeIntTokens (string s, string div) { 35 | vector items; 36 | int i=0, j; 37 | 38 | for (i=s.find_first_not_of(div, i); i!=-1; i=s.find_first_not_of(div, i=j)) { 39 | j = s.find_first_of(div, i); 40 | items.push_back(atoi(s.substr(i, j-i).c_str())); 41 | } 42 | return items; 43 | } 44 | 45 | 46 | int main () { 47 | string testString = "This is a test", testInt = "4:5:6:7:8"; 48 | unsigned int i; 49 | 50 | vector resString = makeStringTokens(testString, " "); 51 | vectorresInt = makeIntTokens(testInt, ":"); 52 | 53 | cout << "Result of tokenizing the string: \"" 54 | << testString 55 | << "\"" << endl; 56 | 57 | for (i=0; i pot(u, v) - cost[v][u]) { 30 | d[v] = pot(u, v) - cost[v][u]; 31 | p[v] = u; 32 | } 33 | if(!mark[v] && f[u][v] < cap[u][v] && d[v] > pot(u, v) + cost[u][v]) { 34 | d[v] = pot(u, v) + cost[u][v]; 35 | p[v] = u; 36 | } 37 | } 38 | } 39 | for(int i = 0; i < n; i++) 40 | if(pi[i] < inf) pi[i] += d[i]; 41 | return mark[t]; 42 | } 43 | void mcf() { 44 | memset(f, 0, sizeof f); 45 | memset(pi, 0, sizeof pi); 46 | Flow = Cost = 0; 47 | while(dijkstra()) { 48 | int min = inf; 49 | for(int x = t; x != s; x = p[x]) 50 | if(f[x][p[x]]) 51 | min = std::min(f[x][p[x]], min); 52 | else 53 | min = std::min(cap[p[x]][x] - f[p[x]][x], min); 54 | for(int x = t; x != s; x = p[x]) 55 | if(f[x][p[x]]) { 56 | f[x][p[x]] -= min; 57 | Cost -= min * cost[x][p[x]]; 58 | } else { 59 | f[p[x]][x] += min; 60 | Cost += min * cost[p[x]][x]; 61 | } 62 | Flow += min; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Parsing/infix_to_postfix.c: -------------------------------------------------------------------------------- 1 | /* Parsing: Converting infix to postfix 2 | ================================================================= 3 | Description: Given a infix expression in a string, as well as 4 | rules for prescedence of binary operators, returns 5 | the postfix version of the expression. 6 | 7 | Complexity: O(N) where N is the size of the string 8 | ----------------------------------------------------------------- 9 | Author: Gilbert Lee 10 | Date: Sept 13, 2002 11 | References: www.cs.usyd.edu.au/~loki/cs2ll/infix/InToPost.html 12 | ----------------------------------------------------------------- 13 | Reliability: 1 successful use (Spain Problem 727) Sept 2002 14 | Notes: The string should not contain any spaces. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #define MAXN 1000 21 | int pres[300]; 22 | 23 | void setPres(char op, int p){ 24 | pres[(int)op] = p; 25 | } 26 | 27 | void infix_to_postfix(char *infix, char *post){ 28 | int stack[MAXN]; 29 | int head = 0, len = strlen(infix); 30 | int pos = 0, i; 31 | 32 | for(i = 0; i < len; i++){ 33 | switch(infix[i]){ 34 | case '(': stack[head++] = infix[i]; break; 35 | case ')': 36 | while(stack[--head] != '('){ 37 | post[pos++] = stack[head]; 38 | } 39 | break; 40 | case '+': case '-': case '*': case '/': 41 | while(head && pres[stack[head-1]] >= pres[(int)infix[i]]){ 42 | post[pos++] = stack[--head]; 43 | } 44 | stack[head++] = infix[i]; 45 | break; 46 | default: 47 | post[pos++] = infix[i]; 48 | } 49 | } 50 | while(head){ 51 | post[pos++] = stack[--head]; 52 | } 53 | post[pos] = 0; 54 | } 55 | 56 | int main(){ 57 | char infix[MAXN]; 58 | char postfix[MAXN]; 59 | 60 | setPres('+', 1); 61 | setPres('-', 1); 62 | setPres('*', 2); 63 | setPres('/', 2); 64 | 65 | while(scanf(" %s", infix) == 1){ 66 | printf("Infix: [%s] ", infix); 67 | infix_to_postfix(infix, postfix); 68 | printf("Postfix: [%s]\n", postfix); 69 | } 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /misc/roman.cc: -------------------------------------------------------------------------------- 1 | /* Miscellaneous: Roman Numerals 2 | ================================================================= 3 | Description: Converts an arabic number (as an int) to roman 4 | numerals (as a null-terminated string) and vice versa. 5 | 6 | Complexity: O(1) 7 | ----------------------------------------------------------------- 8 | Author: Ashley Zinyk 9 | Date: March 07, 2003 10 | References: http://www.wilkiecollins.demon.co.uk/roman/front.htm 11 | ----------------------------------------------------------------- 12 | Reliability: 0 13 | Notes: Remember that the romans didn't use negative 14 | numbers or the number zero, so those aren't valid 15 | numbers. Numbers greater than or equal to 5000 16 | aren't valid either; those roman numbers can't 17 | easily be represented in ASCII. 18 | 19 | The romans didn't have well-defined numbers; this 20 | implementation uses the rules you see for dating 21 | television shows, so things like IX are legal, 22 | but IM is not. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | using namespace std; 30 | 31 | map > dict; 32 | 33 | char nums[5000][20]; 34 | 35 | void gen_roman() { 36 | char *roman[13] = 37 | {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"}; 38 | int i, j, n, arab[13] = {1000,900,500,400,100,90,50,40,10,9,5,4,1}; 39 | string key; 40 | 41 | for (i = 0; i < 5000; i++) { 42 | nums[i][0] = 0; 43 | for (n = i, j = 0; n; j++) 44 | for (; n >= arab[j]; n -= arab[j]) 45 | strcat(nums[i],roman[j]); 46 | key = nums[i]; 47 | dict[key] = i; 48 | } 49 | } 50 | 51 | char *to_roman(int n) { 52 | if (n < 1 || n >= 5000) return 0; 53 | return nums[n]; 54 | } 55 | 56 | int to_arabic(char *in) { 57 | string key = in; 58 | 59 | if (!dict.count(key)) return -1; 60 | return dict[key]; 61 | } 62 | 63 | int main() { 64 | int i; 65 | 66 | gen_roman(); 67 | for (i = 1; i < 5000; i++) 68 | printf("%d = %s\n",to_arabic(to_roman(i)),to_roman(i)); 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /2d_geometry/isect_iline.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry - Infinite Line Intersection 2 | ================================================================= 3 | Description: Given two infinite lines specified by two points, 4 | determines whether they intersect at one point, 5 | infinitely many points, or no points. In the first 6 | case, the point of intersection is also returned. 7 | The points of a line must be different (otherwise, 8 | the line is not define). 9 | 10 | Complexity: O(1) 11 | ----------------------------------------------------------------- 12 | Author: Howard Cheng 13 | Date: Nov 01, 2003 14 | References: www.exaflop.org/docs/cgafaq/cga1.html 15 | ----------------------------------------------------------------- 16 | Reliability: 0 17 | Notes: - returns 1 if intersect at a point 18 | - returns 0 if no intersection 19 | - returns -1 if lines coincide 20 | */ 21 | #include 22 | #include 23 | 24 | typedef struct{ 25 | double x, y; 26 | } Point; 27 | 28 | #define EPS 1e-8 29 | 30 | int isect_iline(Point a, Point b, Point c, Point d, Point *p){ 31 | double r, denom, num1; 32 | 33 | num1 = (a.y - c.y) * (d.x - c.x) - (a.x - c.x) * (d.y - c.y); 34 | denom = (b.x - a.x) * (d.y - c.y) - (b.y - a.y) * (d.x - c.x); 35 | 36 | if (fabs(denom) >= EPS) { 37 | r = num1 / denom; 38 | p->x = a.x + r*(b.x - a.x); 39 | p->y = a.y + r*(b.y - a.y); 40 | return 1; 41 | } 42 | if (fabs(num1) >= EPS) return 0; 43 | return -1; 44 | } 45 | 46 | int main(){ 47 | Point a, b, c, d, p; int res; 48 | 49 | while (scanf("%lf %lf %lf %lf %lf %lf %lf %lf", 50 | &a.x, &a.y, &b.x, &b.y, &c.x, &c.y, &d.x, &d.y) == 8) { 51 | res = isect_iline(a, b, c, d, &p); 52 | if (res == 1) { 53 | printf("Intersect at (%0.2f, %0.2f)\n", p.x, p.y); 54 | } else if (res == 0) { 55 | printf("Don't intersect\n"); 56 | } else { 57 | printf("Infinite number of intersections\n"); 58 | } 59 | } 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /world_finals/src/code/Graph/Cut vertices and 2-connected components.cpp: -------------------------------------------------------------------------------- 1 | // Input (zerobased): 2 | // g[n] should be the adjacency list of the graph 3 | // g[i] is a vector of int 4 | // Output of cut_ver(): 5 | // cut_vertex is a vector of int 6 | // comp[comp_size] contains the 2 connected components 7 | // comp[i] is a vector of int 8 | const int maxn = 1000; 9 | vector g[maxn]; 10 | int d[maxn], mark[maxn], mark0[maxn], jad[maxn]; 11 | int n; 12 | vector cut_vertex; 13 | // for components only 14 | vector comp[maxn]; 15 | int comp_size; 16 | vector comp_stack; 17 | void dfs(int x, int level) { 18 | mark[x] = 1; 19 | // for components only 20 | comp_stack.push_back(x); 21 | for(int u: g[x]) { 22 | if(!mark[u]) { 23 | jad[u] = d[u] = d[x] + 1; 24 | dfs(u, level + 1); 25 | jad[x] = std::min(jad[u], jad[x]); 26 | if(jad[u] >= d[x] && d[x]) { 27 | cut_vertex.push_back(x); 28 | // for components only 29 | while(comp_stack.back() != u) { 30 | comp[comp_size].push_back(comp_stack.back()); 31 | comp_stack.pop_back(); 32 | } 33 | comp[comp_size].push_back(u); 34 | comp_stack.pop_back(); 35 | comp[comp_size++].push_back(x); 36 | } 37 | } else if(d[u] != d[x] - 1) 38 | jad[x] = std::min(d[u], jad[x]); 39 | } 40 | // for components only 41 | if(level == 0) { 42 | while(comp_stack.size() > 0) { 43 | comp[comp_size].push_back(comp_stack.back()); 44 | comp_stack.pop_back(); 45 | } 46 | comp_size++; 47 | } 48 | } 49 | int dfs0(int x) { 50 | mark0[x] = 1; 51 | for(int to: g[x]) 52 | if(!mark0[to]) return dfs0(to); 53 | return x; 54 | } 55 | void cut_ver() { 56 | memset(mark, 0, sizeof mark); 57 | memset(mark0, 0, sizeof mark0); 58 | memset(d, 0, sizeof d); 59 | memset(jad, 0, sizeof jad); 60 | // for components only 61 | for(int i = 0; i < maxn; i++) comp[i].clear(); 62 | comp_stack.clear(); 63 | comp_size = 0; 64 | cut_vertex.clear(); 65 | for(int i = 0; i < n; i++) 66 | if(!mark[i]) dfs(dfs0(i), 0); 67 | } 68 | -------------------------------------------------------------------------------- /world_finals/src/code/Misc/Calendar.cpp: -------------------------------------------------------------------------------- 1 | const int MONTH_DAYS[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 2 | // epoch is the first year of the world 3 | const int epoch = 1700; 4 | class Date { 5 | public: 6 | // month is zero based 7 | int year, month, day; 8 | Date() {} 9 | Date(int year, int month, int day): year(year), month(month - 1), day(day) {} 10 | bool operator<(const Date &date) const { 11 | if(year != date.year) return year < date.year; 12 | if(month != date.month) return month < date.month; 13 | return day < date.day; 14 | } 15 | friend ostream &operator<<(ostream &out, const Date &date) { 16 | out << date.month + 1 << "/" << date.day << "/" << date.year; 17 | return out; 18 | } 19 | }; 20 | bool isLeap(int year) { 21 | if(year % 400 == 0) return true; 22 | if(year % 100 == 0) return false; 23 | return (year % 4 == 0); 24 | } 25 | int getMonthDays(int year, int month) { 26 | if(month != 1) 27 | return MONTH_DAYS[month]; 28 | else 29 | return isLeap(year) ? 29 : 28; 30 | } 31 | // number of leap years between two years 32 | int leapYears(int from, int to) { // [from, to) 33 | if(from >= to) return 0; 34 | to--; 35 | int fours = to / 4 - from / 4; 36 | int hundreds = to / 100 - from / 100; 37 | int fhundreds = to / 400 - from / 400; 38 | if(isLeap(from)) return fours - hundreds + fhundreds + 1; 39 | return fours - hundreds + fhundreds; 40 | } 41 | int dateToDay(Date date) { 42 | int year = date.year; 43 | int month = date.month; 44 | int day = date.day; 45 | int days = (year - epoch) * 365; 46 | days += leapYears(epoch, year); 47 | for(int i = 0; i < month; i++) days += getMonthDays(year, i); 48 | days += day; 49 | return days; 50 | } 51 | Date dayToDate(int days) { 52 | int year = days / 365; 53 | year += epoch; 54 | days %= 365; 55 | while(days <= leapYears(epoch, year)) { 56 | year--; 57 | days += 365; 58 | } 59 | days -= leapYears(epoch, year); 60 | int month = 0; 61 | for(; month < 12 && days > getMonthDays(year, month); month++) days -= getMonthDays(year, month); 62 | return Date(year, month + 1, days); 63 | } 64 | -------------------------------------------------------------------------------- /num_theory/primefactor.c: -------------------------------------------------------------------------------- 1 | /* Number Theory: Prime Factorization 2 | ================================================================= 3 | Description: Given a positive number N < INT_MAX, produces an 4 | array of it's prime factors. 5 | 6 | Results are returned in a structure called Factors 7 | with the prime factors stored in the array "fact", 8 | of length "size". 9 | 10 | Complexity: roughly O(sqrt(N)) 11 | ----------------------------------------------------------------- 12 | Author: Gilbert Lee 13 | Date: Oct 23, 2002 (fixed MAXN bug) 14 | References: 15 | ----------------------------------------------------------------- 16 | Reliability: 0 17 | Notes: N is assumed to be > 1. 18 | The factors will be returned in increasing order 19 | */ 20 | 21 | #include 22 | 23 | #define MAXN 46340 24 | #define MAXP 5000 25 | 26 | int primes[MAXP]; 27 | int psize; 28 | 29 | void getPrimes(){ 30 | int i, j, isprime; 31 | 32 | psize = 0; 33 | primes[psize++] = 2; 34 | for(i = 3; i <= MAXN; i+= 2){ 35 | for(isprime = j = 1; j < psize; j++){ 36 | if(i % primes[j] == 0){ 37 | isprime = 0; 38 | break; 39 | } 40 | if(1.0*primes[j]*primes[j] > i) break; 41 | } 42 | if(isprime) primes[psize++] = i; 43 | } 44 | } 45 | 46 | typedef struct{ 47 | int size; 48 | int f[32]; 49 | } Factors; 50 | 51 | Factors getPFactor(int n){ 52 | Factors x; 53 | int i; 54 | 55 | x.size = 0; 56 | for(i = 0; i < psize; i++){ 57 | while(n % primes[i] == 0){ 58 | x.f[x.size++] = primes[i]; 59 | n /= primes[i]; 60 | } 61 | if(1.0*primes[i]*primes[i] > n) break; 62 | } 63 | if(n > 1){ 64 | x.f[x.size++] = n; 65 | } 66 | return x; 67 | } 68 | 69 | int main(){ 70 | Factors x; 71 | int i, n; 72 | 73 | getPrimes(); 74 | while(scanf("%d", &n) == 1 && n > 1){ 75 | x = getPFactor(n); 76 | printf("%d = ", n); 77 | for(i = 0; i < x.size; i++){ 78 | if(i) printf(" x "); 79 | printf("%d", x.f[i]); 80 | } 81 | printf("\n"); 82 | } 83 | return 0; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /dynamic/asc_subseq2.c: -------------------------------------------------------------------------------- 1 | /* Dynamic Programming: Longest ascending subsequence (N^2 version) 2 | ================================================================= 3 | Description: Given an array of size N, asc_seq returns the length 4 | of the longest ascending subsequence, and stores one 5 | such subsequence in the array S. 6 | 7 | Ascending is defined by cmp(A,B), which returns 8 | 1 if A may come after B in the sequence, and 0 9 | otherwise 10 | 11 | Complexity: O(N^2) 12 | ----------------------------------------------------------------- 13 | Author: Gilbert Lee 14 | Date: Jan 16, 2003 15 | References: 16 | ----------------------------------------------------------------- 17 | Reliability: 0 18 | Notes: - To support other data types, just redefine Item 19 | and cmp 20 | - Various cmp functions are included below 21 | */ 22 | 23 | #include 24 | #define MAXN 500 25 | 26 | typedef int Item; 27 | 28 | int cmp(Item a, Item b){ 29 | return a >= b; /* Ascending (Nondecreasing) */ 30 | return a > b; /* Strictly ascending */ 31 | return a <= b; /* Descending (Nonincreasing) */ 32 | return a < b; /* Strictly descending */ 33 | } 34 | 35 | int longest(int n, Item *A, Item *S){ 36 | int most = 0, mi, i, j, last[MAXN], len[MAXN]; 37 | 38 | for(i = 0; i < n; i++){ 39 | len[i] = 1; 40 | for(j = 0; j < i; j++) 41 | if(cmp(A[i], A[j]) && len[j]+1 > len[i]){ 42 | len[i] = len[j]+1; 43 | last[i] = j; 44 | } 45 | if(len[i] > most){ 46 | most = len[i]; 47 | mi = i; 48 | } 49 | } 50 | 51 | /* Skip if you do not need to build S */ 52 | for(i = most-1; i >= 0; i--){ 53 | S[i] = A[mi]; 54 | mi = last[mi]; 55 | } 56 | return most; 57 | } 58 | 59 | int main(){ 60 | int n, result, i; 61 | Item A[MAXN], S[MAXN]; 62 | 63 | scanf("%d", &n); 64 | for(i = 0; i < n; i++) scanf("%d", &A[i]); 65 | result = longest(n, A, S); 66 | 67 | printf("Size of longest subsequence: %d\n", result); 68 | for(i = 0; i < result; i++) printf("%d ", S[i]); 69 | printf("\n"); 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /misc/sqr_index.c: -------------------------------------------------------------------------------- 1 | /* Miscellaneous: Square index rotation/flipping 2 | ================================================================= 3 | Description: For a square of size n with indices 0..n-1, 4 | Given x and y and a orientation 5 | returns the corresponding x,y coordinate. 6 | 7 | Complexity: O(1) 8 | ----------------------------------------------------------------- 9 | Author: Gilbert Lee 10 | Date: Jan 27, 2003 11 | References: 12 | ----------------------------------------------------------------- 13 | Reliability: 1 Problem G: Noise Effect 14 | (ACM South America - 2002) Jan 26, 2003 15 | Notes: Here are diagrams of the various orientations: 16 | 17 | x y 18 | ^ ^ <--+ +--> 19 | y| |x |y x| 20 | +--> <--+ v v 21 | x y 22 | d=0 d=1 d=2 d=3 23 | 24 | y x 25 | ^ <--+ +--> ^ 26 | |y |x y| x| 27 | <--+ v v +--> 28 | x y 29 | d=4 d=5 d=6 d=7 30 | */ 31 | 32 | #include 33 | 34 | int n, g[10][10]; 35 | 36 | int dx(int x, int y, int d){ 37 | switch(d){ 38 | case 0: case 6: return x; 39 | case 1: case 5: return n-1-y; 40 | case 2: case 4: return n-1-x; 41 | case 3: case 7: return y; 42 | } 43 | return -1; 44 | } 45 | 46 | int dy(int x, int y, int d){ 47 | switch(d){ 48 | case 0: case 4: return y; 49 | case 1: case 7: return x; 50 | case 2: case 6: return n-1-y; 51 | case 3: case 5: return n-1-x; 52 | } 53 | return -1; 54 | } 55 | 56 | int main(){ 57 | int i, j, d; 58 | 59 | scanf("%d", &n); 60 | 61 | for(i = 0; i < n; i++) 62 | for(j = 0; j < n; j++) 63 | g[i][j] = i*n+j; 64 | 65 | for(d = 0; d < 8; d++){ 66 | printf("Orientation [%d]\n", d); 67 | for(i = 0; i < n; i++){ 68 | for(j = 0; j < n; j++) 69 | printf("%d", g[dx(i,j,d)][dy(i,j,d)]); 70 | printf("\n"); 71 | } 72 | printf("\n"); 73 | } 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /2d_geometry/point_in_convex_poly.c: -------------------------------------------------------------------------------- 1 | /* 2D Geometry: Point in convex polygon 2 | ================================================================= 3 | Description: Given a point an a convex polygon, returns 1 if the 4 | point is in the polygon 5 | 6 | Can also check to see if point is on boundary 7 | 8 | Complexity: O(N) where N is number of vertices of polygon 9 | ----------------------------------------------------------------- 10 | Author: Ashley Zinyk, Gilbert Lee 11 | Date: Nov 14, 2002 12 | References: 13 | ----------------------------------------------------------------- 14 | Reliability: 0 15 | Notes: 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #define EPS 1E-8 23 | #define BOUNDARY 1 /* What to return if the point is on the 24 | boundary of the polygon (0 = false, 1 = true) */ 25 | 26 | typedef struct{ 27 | double x, y; 28 | } Point; 29 | 30 | double area_tri(Point a, Point b, Point c){ 31 | double area; 32 | 33 | area = (b.x-a.x) * (c.y-a.y) 34 | -(b.y-a.y) * (c.x-a.x); 35 | return (fabs(area))/2; 36 | } 37 | 38 | int point_in_convex_poly(Point *poly, int n, Point p){ 39 | double areapoly = 0, areatri = 0, temp; 40 | int bflag = 0; 41 | int i, j; 42 | 43 | for(i = 0, j = n-1; i < n; j = i++){ 44 | areapoly += area_tri(poly[i], poly[j], poly[0]); 45 | temp = area_tri(poly[i], poly[j], p); 46 | if(temp < EPS) bflag = 1; 47 | areatri += temp; 48 | } 49 | if(fabs(areapoly-areatri) < EPS){ 50 | if(bflag) return BOUNDARY; 51 | else return 1; 52 | } 53 | return 0; 54 | } 55 | 56 | int main(){ 57 | int i, n; 58 | Point *poly, p; 59 | 60 | printf("How many vertices in the polygon? "); 61 | scanf("%d", &n); 62 | poly = (Point *) malloc(n*sizeof(Point)); 63 | for(i = 0; i < n; i++){ 64 | scanf("%lf %lf", &poly[i].x, &poly[i].y); 65 | } 66 | printf("Now enter points to test:\n"); 67 | while(scanf("%lf %lf", &p.x, &p.y) == 2){ 68 | if(point_in_convex_poly(poly, n, p)){ 69 | printf("YES\n"); 70 | } else { 71 | printf("NO\n"); 72 | } 73 | } 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /2d_geometry/pt_leftright.c: -------------------------------------------------------------------------------- 1 | /* 2D_Geometry: Point Left/Right/In Line test 2 | =================================================================== 3 | Description: 4 | Given a directed line segment and a point, this code returns 5 | whether the point is to the left of, to the right of, or colinear 6 | with the line segment. 7 | 8 | Complexity: O(1) 9 | ------------------------------------------------------------------- 10 | Author: Jason Klaus 11 | Date: Nov 8, 2002 12 | 13 | References: Based on Cross products, pg.936, 14 | Introduction to Algorithms (2nd Edition), 15 | Cormen, Leiserson, Rivest, Stein 16 | ------------------------------------------------------------------- 17 | Reliability: 0 successes. 18 | 19 | Notes: 20 | - The line segment runs from Point a to Point b 21 | - If Point a == Point b, then any Point p will be considered 22 | colinear. 23 | - The point to be compared is Point p. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #define EPSILON 1E-10 32 | 33 | typedef struct { 34 | double x, y; 35 | } Point; 36 | 37 | enum {LEFT, RIGHT, CL}; 38 | 39 | int pt_leftright(Point a, Point b, Point p) 40 | { 41 | double res; 42 | 43 | res = (p.x - a.x)*(b.y - a.y) - 44 | (p.y - a.y)*(b.x - a.x); 45 | 46 | if (fabs(res) < EPSILON) 47 | return CL; 48 | else if (res > 0.0) 49 | return RIGHT; 50 | return LEFT; 51 | } 52 | 53 | int main(void) 54 | { 55 | Point a, b, p; 56 | int res; 57 | 58 | while (scanf("%lf %lf %lf %lf %lf %lf", &a.x, &a.y, &b.x, &b.y, 59 | &p.x, &p.y) == 6) { 60 | res = pt_leftright(a, b, p); 61 | 62 | printf("(%.2lf, %.2lf) is ", p.x, p.y); 63 | 64 | switch (res) { 65 | case LEFT: 66 | printf("Left of"); 67 | break; 68 | case RIGHT: 69 | printf("Right of"); 70 | break; 71 | default: 72 | printf("Co-Linear with"); 73 | break; 74 | } 75 | 76 | printf(" the line segment (%.2lf, %.2lf) -> (%.2lf, %.2lf)\n", 77 | a.x, a.y, b.x, b.y); 78 | } 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /combinatorics/necklace.c: -------------------------------------------------------------------------------- 1 | /* Combinatorics: Necklace/Bracelet Enumeration 2 | ================================================================= 3 | Description: Calculate the number of necklaces/bracelets with N 4 | beads of K different colors. 5 | 6 | Necklaces are unique up to rotation while bracelets 7 | can be reflected as well (i.e. mirror images count 8 | only once) 9 | 10 | Complexity: O(N^2) 11 | ----------------------------------------------------------------- 12 | Author: Gilbert Lee 13 | Date: Nov 13, 2002 14 | References: 15 | ----------------------------------------------------------------- 16 | Reliability: 1 Successful use (Spain 10294) 17 | Notes: Burnside Lemma's states that the number of such is 18 | equal to the total sum of all invariants / # of 19 | transformations. 20 | Basically, this is what the algorithm calculates. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | #define MAXN 51 27 | 28 | int seen[MAXN]; 29 | 30 | double getNecklaces(int n, int t){ 31 | int r, i, pos; 32 | double p, sum = 0; 33 | 34 | for(r = 0; r < n; r++){ 35 | memset(seen, 0, sizeof(seen)); 36 | p = 1; 37 | for(i = 0; i < n; i++){ 38 | if(seen[i]) continue; 39 | p *= t; 40 | seen[i] = 1; 41 | pos = i; 42 | while(!seen[(pos+r)%n]){ 43 | pos += r; 44 | pos %= n; 45 | seen[pos] = 1; 46 | } 47 | } 48 | sum += p; 49 | } 50 | return sum/n; 51 | } 52 | 53 | double getBracelets(int n, int t){ 54 | int r, i, pos; 55 | double p, sum; 56 | 57 | sum = n*getNecklaces(n, t); 58 | for(r = 0; r < n; r++){ 59 | memset(seen, 0, sizeof(seen)); 60 | p = 1; 61 | for(i = 0; i < n; i++){ 62 | if(seen[i]) continue; 63 | p *= t; 64 | pos = i; 65 | while(!seen[(2*n-(pos+r))%n]){ 66 | pos = (2*n-(pos+r))%n; 67 | seen[pos] = 1; 68 | } 69 | } 70 | sum += p; 71 | } 72 | return sum/(2*n); 73 | } 74 | 75 | int main(){ 76 | int n, k; 77 | 78 | while(scanf("%d %d", &n, &k) == 2){ 79 | printf("%.0f %.0f\n", getNecklaces(n,k), getBracelets(n,k)); 80 | } 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /graph/bellmanford.c: -------------------------------------------------------------------------------- 1 | /* Graph Theory: Bellman-Ford Algorithm - negative weigth cycles 2 | ================================================================= 3 | Description: Given a directed graph G, expressed in terms of its 4 | edges, and a source vertex s, Bellman-Ford returns 5 | whether or not it is possible to encounter a cycle 6 | of negative weight. If such a cycle exists, it 7 | returns 0, otherwise 1. 8 | 9 | If no negative-weight cycle exists, then dist[v] 10 | contains the shortest distance from source s to 11 | v. 12 | 13 | Complexity: O(NM) where N is # of nodes, M is # of edges 14 | ----------------------------------------------------------------- 15 | Author: Gilbert Lee 16 | Date: Sept 20, 2002 17 | References: 18 | ----------------------------------------------------------------- 19 | Reliability: 1 successful use (Sept 2002) 20 | (Spain 558) 21 | Notes: INF must be set to a value larger than any edge 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #define INF INT_MAX 29 | #define MAXNODES 1005 30 | #define MAXEDGES 2005 31 | 32 | typedef struct{ 33 | int u,v,w; 34 | } Edge; 35 | 36 | int dist[MAXNODES], pred[MAXNODES]; 37 | Edge edge[MAXEDGES]; 38 | int n, m; 39 | 40 | int BellmanFord(int source){ 41 | int i, j; 42 | 43 | for(i = 0; i < n; i++){ 44 | dist[i] = INF; 45 | pred[i] = -1; 46 | } 47 | dist[source] = 0; 48 | 49 | for(i = 0; i < n-1; i++) 50 | for(j = 0; j < m; j++){ 51 | if(dist[edge[j].v] > dist[edge[j].u]+edge[j].w){ 52 | dist[edge[j].v] = dist[edge[j].u]+edge[j].w; 53 | pred[edge[j].v] = edge[j].u; 54 | } 55 | } 56 | 57 | for(j = 0; j < m; j++){ 58 | if(dist[edge[j].v] > dist[edge[j].u]+edge[j].w) return 0; 59 | } 60 | return 1; 61 | } 62 | 63 | int main(){ 64 | int tnum, i; 65 | 66 | scanf("%d", &tnum); 67 | while(tnum--){ 68 | scanf("%d %d", &n, &m); 69 | for(i = 0; i < m; i++){ 70 | scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w); 71 | } 72 | if(BellmanFord(0)) printf("not "); 73 | printf("possible\n"); 74 | } 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /generators/pyth.c: -------------------------------------------------------------------------------- 1 | /* Generators: Pythagorean Triples 2 | ================================================================= 3 | Description: A Pythagorean triple is a set of three positive 4 | integers a < b < c such that a^2 + b^2 = c^2. A 5 | primitive triple has the property that a,b,c are 6 | relatively prime. Given N, this code generates 7 | all the primitive triples such that c < N. 8 | 9 | Complexity: O(N) 10 | ----------------------------------------------------------------- 11 | Author: Ashley Zinyk 12 | Date: Dec 15, 2002 13 | References: Leonhard Euler, so you know it's fast. 14 | ----------------------------------------------------------------- 15 | Reliability: 1 (Spain 106) 16 | Notes: There will be no more than N/4 triples generated; 17 | allocate this much space. The function will 18 | return the actual number of triples generated. 19 | The triples will be in no particular order; you may 20 | want to sort the results after generating them. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | typedef struct { 27 | int a, b, c; 28 | } ptrip; 29 | 30 | int gcd(int a, int b) { 31 | int r; 32 | 33 | while (b) { 34 | r = a % b; 35 | a = b; 36 | b = r; 37 | } 38 | return a; 39 | } 40 | 41 | int gen_triples(int n, ptrip *res) { 42 | int a, b, p, q, cnt = 0; 43 | 44 | for (p = 2; p*p < n; p++) { 45 | for (q = 1+p%2; q < p && p*p+q*q < n; q += 2) { 46 | if (gcd(p,q)!=1) continue; 47 | a = p*p-q*q; 48 | b = 2*p*q; 49 | if (a < b) { res[cnt].a = a; res[cnt].b = b; } 50 | else { res[cnt].a = b; res[cnt].b = a; } 51 | res[cnt++].c = p*p+q*q; 52 | } 53 | } 54 | return cnt; 55 | } 56 | 57 | int main() { 58 | ptrip *arra = NULL; 59 | int i, max, ntrip; 60 | 61 | while (scanf("%d",&max)==1) { 62 | arra = realloc(arra,sizeof(ptrip)*max/4); 63 | ntrip = gen_triples(max,arra); 64 | printf("%d\n",ntrip); 65 | for (i = 0; i < ntrip; i++) 66 | printf("%d %d %d\n", arra[i].a, arra[i].b, arra[i].c); 67 | } 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /world_finals/src/code/Graph/Fast flow.cpp: -------------------------------------------------------------------------------- 1 | // find_flow returns max flow from s to t in an n-vertex graph. 2 | // Use add_edge to add edges (directed/undirected) to the graph. 3 | // Call clear_flow() before each testcase. 4 | const int maxn = 1000; 5 | int c[maxn][maxn]; 6 | vector adj[maxn]; 7 | int par[maxn]; 8 | int dcount[maxn + maxn]; 9 | int dist[maxn]; 10 | void add_edge(int a, int b, int cap, int rev_cap = 0) { 11 | c[a][b] += cap; 12 | c[b][a] += rev_cap; 13 | adj[a].push_back(b); 14 | adj[b].push_back(a); 15 | } 16 | void clear_flow() { 17 | memset(c, 0, sizeof c); 18 | memset(dcount, 0, sizeof dcount); 19 | for(int i = 0; i < maxn; ++i) adj[i].clear(); 20 | } 21 | int advance(int v) { 22 | for(int w: adj[v]) 23 | if(c[v][w] > 0 && dist[v] == dist[w] + 1) { 24 | par[w] = v; 25 | return w; 26 | } 27 | return -1; 28 | } 29 | int retreat(int v) { 30 | int old = dist[v]; 31 | --dcount[dist[v]]; 32 | for(int w: adj[v]) 33 | if(c[v][w] > 0) dist[v] = min(dist[v], dist[w]); 34 | ++dist[v]; 35 | ++dcount[dist[v]]; 36 | if(dcount[old] == 0) return -1; 37 | return par[v]; 38 | } 39 | int augment(int s, int t) { 40 | int delta = c[par[t]][t]; 41 | for(int v = t; v != s; v = par[v]) delta = min(delta, c[par[v]][v]); 42 | for(int v = t; v != s; v = par[v]) { 43 | c[par[v]][v] -= delta; 44 | c[v][par[v]] += delta; 45 | } 46 | return delta; 47 | } 48 | queue q; 49 | void bfs(int v) { 50 | memset(dist, -1, sizeof dist); 51 | while(!q.empty()) q.pop(); 52 | q.push(v); 53 | dist[v] = 0; 54 | ++dcount[dist[v]]; 55 | while(!q.empty()) { 56 | v = q.front(); 57 | q.pop(); 58 | for(int w: adj[v]) 59 | if(c[w][v] > 0 && dist[w] == -1) { 60 | dist[w] = dist[v] + 1; 61 | ++dcount[dist[w]]; 62 | q.push(w); 63 | } 64 | } 65 | } 66 | int find_flow(int n, int s, int t) { 67 | bfs(t); 68 | int v = s; 69 | par[s] = s; 70 | int ans = 0; 71 | while(v != -1 && dist[s] < n) { 72 | int newv = advance(v); 73 | if(newv != -1) v = newv; 74 | else v = retreat(v); 75 | if(v == t) ans += augment(v = s, t); 76 | } 77 | return ans; 78 | } 79 | -------------------------------------------------------------------------------- /2d_geometry/ccw.c: -------------------------------------------------------------------------------- 1 | /* 2D Geometry: CCW Orientation analysis 2 | ================================================================= 3 | Description: Given three points a, b, c, it returns whether the 4 | path from a to b to c is counterclockwise, clockwise 5 | or undefined. 6 | 7 | Undefined is returned if the 3 points are colinear, 8 | and c is between a and b. 9 | 10 | Complexity: O(1) 11 | ----------------------------------------------------------------- 12 | Author: Howard Cheng, Scott Crosswhite, Gilbert Lee 13 | Date: Nov 13, 2002 14 | References: wilma.cs.brown.edu/courses/cs016/packet/node18.html 15 | ----------------------------------------------------------------- 16 | Reliability: 0 17 | Notes: Colinearity with respect to the line through a, b, 18 | and c: 19 | CCW for c in [b, +inf) 20 | CNEITHER for c in [a,b) 21 | CW for c in (-inf, a) 22 | 23 | For true CW/CCW/Collinear testing, consider using 24 | pt_leftright.c 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | /* how close to call equal */ 32 | #define EPS 1E-8 33 | #define SQR(x) ((x)*(x)) 34 | 35 | typedef struct { 36 | double x, y; 37 | } Point; 38 | 39 | /* counterclockwise, clockwise, or undefined */ 40 | enum {CCW, CW, CNEITHER}; 41 | 42 | int ccw(Point a, Point b, Point c) 43 | { 44 | double dx1 = b.x - a.x, dx2 = c.x - b.x; 45 | double dy1 = b.y - a.y, dy2 = c.y - b.y; 46 | double t1 = dx1 * dy2; 47 | double t2 = dx2 * dy1; 48 | 49 | if(fabs(t1 - t2) < EPS) { 50 | if(dx1 * dx2 < 0 || dy1 * dy2 < 0) { 51 | if(SQR(dx1)+SQR(dy1) >= SQR(dx2)+SQR(dy2)- EPS) return CNEITHER; 52 | return CW; 53 | } 54 | return CCW; 55 | } 56 | return t1 > t2 ? CCW : CW; 57 | } 58 | 59 | int main(void) 60 | { 61 | Point a, b, c; 62 | int a1, a2, a3, a4, a5, a6; 63 | int res; 64 | 65 | while (scanf("%lf %lf %lf %lf %lf %lf", 66 | &a.x, &a.y, &b.x, &b.y, &c.x, &c.y) == 6){ 67 | res = ccw(a,b,c); 68 | if (res == CW) { 69 | printf("CW\n"); 70 | } else if (res == CCW) { 71 | printf("CCW\n"); 72 | } else if (res == CNEITHER) { 73 | printf("CNEITHER\n"); 74 | } 75 | } 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /generators/gen_bin_card.c: -------------------------------------------------------------------------------- 1 | /* Generators: Binary Strings generator - (ordered by cardinality) 2 | ================================================================= 3 | Description: Generates all possible binary strings of size N 4 | ordered in increasing order by the number of bits 5 | set, then lexographically. 6 | For example: when N = 3, the routine generates: 7 | 0 0 0 ] Cardinality 0 8 | 0 0 1 ] 9 | 0 1 0 | Cardinality 1 10 | 1 0 0 ] 11 | 0 1 1 ] 12 | 1 0 1 | Cardinality 2 13 | 1 1 0 ] 14 | 1 1 1 ] Cardinality 3 15 | 16 | Complexity: O(2^N) 17 | ----------------------------------------------------------------- 18 | Author: Gilbert Lee 19 | Date: Sept 9, 2002 20 | References: 21 | ----------------------------------------------------------------- 22 | Reliability: 0 23 | Notes: This routine may be useful if we want to find the 24 | solution with the lowest cardinality. 25 | For example, you may want to break off a search 26 | after a certain number of solutions have been found. 27 | */ 28 | 29 | #include 30 | 31 | #define MAXN 20 32 | 33 | char bit[MAXN]; 34 | 35 | /* Add whatever work needs to be done in this routine */ 36 | /* For this sample, we just print out the bits */ 37 | void Process(int n){ 38 | int i; 39 | 40 | for(i = 0; i < n; i++) printf("%2d", bit[i]); 41 | printf("\n"); 42 | } 43 | 44 | void recurse(int n, int curr, int left){ 45 | if(curr == n){ 46 | Process(n); 47 | } else { 48 | if(curr+left < n){ 49 | bit[curr] = 0; 50 | recurse(n, curr+1, left); 51 | } 52 | if(left){ 53 | bit[curr] = 1; 54 | recurse(n, curr+1, left-1); 55 | } 56 | } 57 | } 58 | 59 | /* This function generates the strings based on cardinality 60 | You may wish to add break conditions in this routine if 61 | necessary */ 62 | void gen_bin_card(int n){ 63 | int i; 64 | 65 | for(i = 0; i <= n; i++){ 66 | printf("Cardinality %d:\n", i); 67 | recurse(n, 0, i); 68 | } 69 | } 70 | 71 | int main(){ 72 | int n; 73 | 74 | while(scanf("%d", &n) == 1){ 75 | printf("Binary string length N = %d\n", n); 76 | gen_bin_card(n); 77 | } 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/windows,osx,linux,c,c++,java 2 | 3 | ### Windows ### 4 | # Windows image file caches 5 | Thumbs.db 6 | ehthumbs.db 7 | 8 | # Folder config file 9 | Desktop.ini 10 | 11 | # Recycle Bin used on file shares 12 | $RECYCLE.BIN/ 13 | 14 | # Windows Installer files 15 | *.cab 16 | *.msi 17 | *.msm 18 | *.msp 19 | 20 | # Windows shortcuts 21 | *.lnk 22 | 23 | 24 | ### OSX ### 25 | .DS_Store 26 | .AppleDouble 27 | .LSOverride 28 | 29 | # Icon must end with two \r 30 | Icon 31 | 32 | # Thumbnails 33 | ._* 34 | 35 | # Files that might appear in the root of a volume 36 | .DocumentRevisions-V100 37 | .fseventsd 38 | .Spotlight-V100 39 | .TemporaryItems 40 | .Trashes 41 | .VolumeIcon.icns 42 | 43 | # Directories potentially created on remote AFP share 44 | .AppleDB 45 | .AppleDesktop 46 | Network Trash Folder 47 | Temporary Items 48 | .apdisk 49 | 50 | 51 | ### Linux ### 52 | *~ 53 | 54 | # KDE directory preferences 55 | .directory 56 | 57 | # Linux trash folder which might appear on any partition or disk 58 | .Trash-* 59 | 60 | 61 | ### C ### 62 | # Object files 63 | *.o 64 | *.ko 65 | *.obj 66 | *.elf 67 | 68 | # Precompiled Headers 69 | *.gch 70 | *.pch 71 | 72 | # Libraries 73 | *.lib 74 | *.a 75 | *.la 76 | *.lo 77 | 78 | # Shared objects (inc. Windows DLLs) 79 | *.dll 80 | *.so 81 | *.so.* 82 | *.dylib 83 | 84 | # Executables 85 | *.exe 86 | *.out 87 | *.app 88 | *.i*86 89 | *.x86_64 90 | *.hex 91 | 92 | # Debug files 93 | *.dSYM/ 94 | 95 | 96 | ### C++ ### 97 | # Compiled Object files 98 | *.slo 99 | *.lo 100 | *.o 101 | *.obj 102 | 103 | # Precompiled Headers 104 | *.gch 105 | *.pch 106 | 107 | # Compiled Dynamic libraries 108 | *.so 109 | *.dylib 110 | *.dll 111 | 112 | # Fortran module files 113 | *.mod 114 | 115 | # Compiled Static libraries 116 | *.lai 117 | *.la 118 | *.a 119 | *.lib 120 | 121 | # Executables 122 | *.exe 123 | *.out 124 | *.app 125 | 126 | 127 | ### Java ### 128 | *.class 129 | 130 | # Mobile Tools for Java (J2ME) 131 | .mtj.tmp/ 132 | 133 | # Package Files # 134 | *.jar 135 | *.war 136 | *.ear 137 | 138 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 139 | hs_err_pid* 140 | 141 | -------------------------------------------------------------------------------- /2d_geometry/area_poly.cpp: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Area of a polygon 2 | ================================================================= 3 | Description: Given a polygon represented as an array of N points, 4 | returns the signed area. The result is positive if 5 | the orientation is counterclockwise, and negative 6 | otherwise. 7 | Complexity: O(N) N being the number of vertices of the polygon 8 | ----------------------------------------------------------------- 9 | Author: Howard Cheng, Gilbert Lee 10 | Date: Sept 2002 11 | References: www.exaflop.org/docs/cgafaq/cga2.html 12 | ----------------------------------------------------------------- 13 | Editor: Morgan Redshaw 14 | Date: January 2016 15 | 16 | Changes: Changed to use c++ 17 | Used complex for point rather than specialized struct 18 | ----------------------------------------------------------------- 19 | Editor: Ian DeHaan 20 | Date: July 2019 21 | 22 | Changes: Fixed it so that it compiles 23 | Added reliability 24 | ----------------------------------------------------------------- 25 | Reliability: 26 | UVa 10065 27 | Kattis polygonarea 28 | Kattis convexpolygonarea 29 | 30 | Notes: Remember to run fabs() on the result if a positive 31 | area is desired. 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | using namespace std; 39 | 40 | typedef complex Point; 41 | 42 | double cross(const Point &a, const Point &b) { 43 | return imag(conj(a)*b); 44 | } 45 | 46 | double area_poly(const vector &p){ 47 | double sum = 0; 48 | 49 | for(int i = p.size()-1, j = 0; j < p.size(); i = j++) 50 | sum += cross(p[i], p[j]); 51 | 52 | return sum/2.0; 53 | } 54 | 55 | int main(){ 56 | vector poly; 57 | int i, n; 58 | 59 | while(cin >> n, n > 0) 60 | { 61 | poly.resize(n); 62 | 63 | for(i = 0; i < n; i++) 64 | { 65 | double x, y; 66 | cin >> x >> y; 67 | poly[i] = Point(x, y); 68 | } 69 | printf("Signed Area = %f\n", area_poly(poly)); 70 | } 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /arithmetic/t_func.c: -------------------------------------------------------------------------------- 1 | /* Miscellaneous: Coupons Problem 2 | ================================================================= 3 | Description: Coupons are given away in boxes of cereal. There are 4 | 'm' different kinds of coupons (with equiprobable 5 | distribution). How many boxes of cereal would you 6 | have to buy, on average, to collect them all? 7 | 8 | Complexity: O(N) 9 | ----------------------------------------------------------------- 10 | Author: Ashley Zinyk 11 | Date: March 19, 2003 12 | References: http://mathforum.org/library/drmath/view/56657.html 13 | ----------------------------------------------------------------- 14 | Reliability: 0 15 | Notes: 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | double ncoupons(int m) { 23 | double num = 0.0; 24 | int i; 25 | 26 | for (i = 1; i <= m; i++) num += m/(double) i; 27 | return num; 28 | } 29 | 30 | /* A related problem: If you buy 'n' boxes of cereal, what is the 31 | probability you get at least one of each of the 'm' coupons? 32 | This is solved by the T(n,m) function. The T(n,m) function is 33 | recursive, so this implementation creates a table using dynamic 34 | programming (only once) and queries it thereafter. Like most 35 | combinatoric problems, this one blows up very fast. This solution 36 | works for n < 100. */ 37 | 38 | double nways[100][100]; 39 | 40 | void make_coupon_table() { 41 | double fact = 1.0; 42 | int i, j; 43 | 44 | for (i = 1; i < 100; i++) { 45 | nways[i][1] = 1.0; 46 | for (j = 2; j < i; j++) 47 | nways[i][j] = j*(nways[i-1][j] + nways[i-1][j-1]); 48 | nways[i][i] = fact *= i; 49 | } 50 | } 51 | 52 | double query_table(int m, int n) { 53 | if (n < m) return 0.0; 54 | if (m == 0) return 1.0; 55 | if (n >= 100 || m >= 100) exit(1); 56 | return nways[n][m]/pow(m,n); 57 | } 58 | 59 | int main() { 60 | int i, j; 61 | 62 | for (i = 1; i < 34; i++) 63 | printf("On average, it takes %g boxes to collect all %d\n", 64 | ncoupons(i), i); 65 | make_coupon_table(); 66 | for (i = 0; i < 100; i++) { 67 | printf("With %d boxes, there is a ",i); 68 | printf("%g probability of collecting all 26\n", 69 | query_table(26,i)); 70 | } 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /2d_geometry/lat_poly_pick.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Lattice-polygons - Pick's Theorem 2 | ================================================================= 3 | Description: Given a lattice N-gon (a polygon where ends points 4 | are on integer coordinates), this routine counts 5 | the number of lattice points on the boundary, as 6 | well as the number of interior lattice points. 7 | 8 | Complexity: O(roughly N) (N calls to gcd()) 9 | ----------------------------------------------------------------- 10 | Author: Gilbert Lee 11 | Date: Sept 12, 2002 12 | References: http://mathworld.wolfram.com/PicksTheorem.html 13 | ----------------------------------------------------------------- 14 | Reliability: 1 successful use (Spain 10088) Sept 2002 15 | Notes: Pick's Formula is: A = I + B/2 - 1 16 | where A = area of the closed lattice polygon 17 | I = # of interior lattice points 18 | B = # of lattice points on boundary 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #define MAXN 1005 26 | typedef struct{ 27 | long long x, y; 28 | } Point; 29 | 30 | int gcd(long long a, long long b){ 31 | int r; 32 | 33 | a = abs(a); 34 | b = abs(b); 35 | while (b) { 36 | r = a % b; 37 | a = b; 38 | b = r; 39 | } 40 | return a; 41 | } 42 | 43 | double area_poly(Point *p, int n){ 44 | double sum = 0; 45 | int i, j; 46 | 47 | for(i = n-1, j = 0; j < n; i = j++) 48 | sum += p[i].x * p[j].y - p[i].y * p[j].x; 49 | return sum/2.0; 50 | } 51 | 52 | void lat_poly_pick(Point *p, int n, long long *I, long long *B){ 53 | int i, j, dx, dy; 54 | double A = fabs(area_poly(p, n)); 55 | 56 | *B = 0; 57 | for(i = n-1, j = 0; j < n; i = j++){ 58 | dx = abs(p[i].x - p[j].x); 59 | dy = abs(p[i].y - p[j].y); 60 | *B += gcd(dx,dy); 61 | } 62 | *I = A+1-*B/2.0; 63 | } 64 | 65 | int main(){ 66 | int i, n; 67 | long long numI, numB; 68 | Point p[MAXN]; 69 | 70 | while(scanf("%d", &n) == 1 && n){ 71 | for(i = 0; i < n; i++){ 72 | scanf("%lld %lld", &p[i].x, &p[i].y); 73 | } 74 | lat_poly_pick(p, n, &numI, &numB); 75 | printf("The lattice polygon has %lld interior points and %lld boundary points\n", numI, numB); 76 | } 77 | return 0; 78 | } 79 | 80 | 81 | -------------------------------------------------------------------------------- /num_theory/primes.c: -------------------------------------------------------------------------------- 1 | /* Number Theory: Generating list of primes 2 | ================================================================= 3 | Description: This routine generates primes up to MAXN and stores 4 | them in the array called primes[]. The number of 5 | such primes is counted by psize. 6 | 7 | Complexity: O(n^2) 8 | ----------------------------------------------------------------- 9 | Author: Gilbert Lee 10 | Date: Oct 23, 2002 11 | References: 12 | ----------------------------------------------------------------- 13 | Reliability: 0 14 | Notes: N Primes up to N Run time (P2 333MHz) 15 | ---------------------------------------------------- 16 | 100 25 0m0.005s 17 | 1 000 168 0m0.006s 18 | 10 000 1 229 0m0.012s 19 | 100 000 9 592 0m0.118s 20 | 1 000 000 78 498 0m2.235s 21 | 10 000 000 664 579 0m46.093s 22 | 23 | (Sqrt of INT_MAX) 46 340 4 792 0m0.045s 24 | 25 | - Don't forget to allocate enough room for the 26 | primes (MAXP). 27 | - The sample program includes checking primes up to 28 | INT_MAX (2^31-1) 29 | */ 30 | 31 | #include 32 | 33 | #define MAXN 46340 34 | #define MAXP 5000 35 | 36 | int primes[MAXP]; 37 | int psize; 38 | 39 | void getPrimes(){ 40 | int i, j, isprime; 41 | 42 | psize = 0; 43 | primes[psize++] = 2; 44 | for(i = 3; i <= MAXN; i+= 2){ 45 | for(isprime = j = 1; j < psize; j++){ 46 | if(i % primes[j] == 0){ 47 | isprime = 0; 48 | break; 49 | } 50 | if(1.0*primes[j]*primes[j] > i) break; 51 | } 52 | if(isprime) primes[psize++] = i; 53 | } 54 | } 55 | 56 | int isPrime(int x){ 57 | int i; 58 | 59 | if(x <= 1) return 0; 60 | for(i = 0; i < psize && primes[i]*primes[i] <= x; i++){ 61 | if(x % primes[i] == 0) return 0; 62 | } 63 | return 1; 64 | } 65 | 66 | int main(){ 67 | int i, x; 68 | 69 | getPrimes(); 70 | printf("%d primes between 1 to %d\n", psize, MAXN); 71 | while(scanf("%d", &x) == 1){ 72 | if(isPrime(x)) printf("%d is prime\n", x); 73 | else printf("%d is not prime\n", x); 74 | } 75 | return 0; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /2d_geometry/isect_circ_test.c: -------------------------------------------------------------------------------- 1 | /* 2D Geometry - Circle Intersection Type 2 | ================================================================= 3 | Description: Determines the type of intersection of 2 circles. 4 | Complexity: O(1) 5 | ----------------------------------------------------------------- 6 | Author: Scott Crosswhite 7 | Date: Oct 24, 2002 8 | References: 9 | ----------------------------------------------------------------- 10 | Reliability: 0 11 | Notes: NONE - No intersection 12 | ONE - One intersection (no other common points) 13 | TWO - Two intersections 14 | AEQUALSB - Same circle 15 | AINB, BINA - One circle is in the other 16 | AINB_TANGENT, BINA_TANGENT - As above, with 1 pt tangent 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #define EPSILON 1e-8 24 | 25 | typedef struct { 26 | double x,y; 27 | } Point; 28 | 29 | typedef struct { 30 | Point o; 31 | double r; 32 | } Circle; 33 | 34 | enum int_t {NONE=0, ONE, TWO, AEQUALSB, AINB, BINA, 35 | AINB_TANGENT, BINA_TANGENT}; 36 | 37 | int CIType (Circle A, Circle B) { 38 | double distance, dx = A.o.x - B.o.x, dy = A.o.y - B.o.y; 39 | 40 | distance = sqrt(dx*dx + dy*dy); 41 | 42 | if (distance < EPSILON && fabs(A.r-B.r) < EPSILON) return AEQUALSB; 43 | if (fabs(distance - (A.r + B.r)) < EPSILON) return ONE; 44 | if (distance > A.r + B.r) return NONE; 45 | if (distance + A.r <= B.r) { 46 | if (B.r - (distance+A.r) < EPSILON) return AINB_TANGENT; 47 | return AINB; 48 | } 49 | if (distance + B.r <= A.r) { 50 | if (A.r - (distance+B.r) < EPSILON) return BINA_TANGENT; 51 | return BINA; 52 | } 53 | return TWO; 54 | } 55 | 56 | /* To test output */ 57 | char type_s[8][50] = {"No intersection", 58 | "One intersection", 59 | "Two intersections", 60 | "Circles match", 61 | "A is entirely in B", 62 | "B is entirely in A", 63 | "A is in B and tangent", 64 | "B is in A and tangent"}; 65 | 66 | int main () { 67 | int type; 68 | Circle A, B; 69 | 70 | while (scanf("%lf %lf %lf %lf %lf %lf", 71 | &A.o.x, &A.o.y, &A.r, &B.o.x, &B.o.y, &B.r) == 6) { 72 | 73 | type = CIType(A, B); 74 | printf("Type: %s \n", type_s[type]); 75 | } 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /world_finals/src/code/Graph/Bipartite weighted matching.cpp: -------------------------------------------------------------------------------- 1 | // Input: n, m, w[n][m] (n <= m) 2 | // w[i][j] is the weight between the i-th vertex of part1 3 | // and the j-th vertex of part2. w[i][j] can be any 4 | // integer (including negative values) 5 | // Output: res, size of res is n 6 | const int inf = 1e7; 7 | const int maxn = 200, maxm = 200; 8 | int n, m, w[maxn][maxm], u[maxn], v[maxm]; 9 | int mark[maxn], mate[maxm], matched[maxn]; 10 | int dfs(int x) { 11 | if(x < 0) return 1; 12 | if(mark[x]++) return 0; 13 | for(int i = 0; i < m; i++) 14 | if(u[x] + v[i] - w[x][i] == 0) 15 | if(dfs(mate[i])) return matched[mate[i] = x] = 1; 16 | return 0; 17 | } 18 | void _2matching() { 19 | memset(mate, -1, sizeof mate); 20 | memset(mark, 0, sizeof mark); 21 | memset(matched, 0, sizeof matched); 22 | for(int i = 0; i < n; i++) 23 | for(int j = 0; j < m; j++) 24 | if(mate[j] < 0 && u[i] + v[j] - w[i][j] == 0) { 25 | matched[mate[j] = i] = 1; 26 | break; 27 | } 28 | for(int i = 0; i < n; i++) 29 | if(!matched[i]) 30 | if(dfs(i)) memset(mark, 0, sizeof mark); 31 | } 32 | void wmatching(vector> &res) { 33 | for(int i = 0; i < m; i++) v[i] = 0; 34 | for(int i = 0; i < n; i++) { 35 | u[i] = -inf; 36 | for(int j = 0; j < m; j++) u[i] = max(u[i], w[i][j]); 37 | } 38 | memset(mate, -1, sizeof mate); 39 | memset(matched, 0, sizeof matched); 40 | int counter = 0; 41 | while(counter != n) { 42 | for(int flag = 1; flag;) { 43 | flag = 0; 44 | memset(mark, 0, sizeof mark); 45 | for(int i = 0; i < n; i++) 46 | if(!matched[i] && dfs(i)) { 47 | counter++; 48 | flag = 1; 49 | memset(mark, 0, sizeof mark); 50 | } 51 | } 52 | int epsilon = inf; 53 | for(int i = 0; i < n; i++) 54 | for(int j = 0; j < m; j++) { 55 | if(!mark[i]) continue; 56 | if(mate[j] >= 0) 57 | if(mark[mate[j]]) continue; 58 | epsilon = min(epsilon, u[i] + v[j] - w[i][j]); 59 | } 60 | for(int i = 0; i < n; i++) 61 | if(mark[i]) u[i] -= epsilon; 62 | for(int j = 0; j < m; j++) 63 | if(mate[j] >= 0) 64 | if(mark[mate[j]]) v[j] += epsilon; 65 | } 66 | res.clear(); 67 | for(int i = 0; i < m; i++) 68 | if(mate[i] != -1) res.emplace_back(mate[i], i); 69 | } 70 | -------------------------------------------------------------------------------- /2d_geometry/area_unionrect.c: -------------------------------------------------------------------------------- 1 | /* 2D-Geometry: Area of the union of Rectangles 2 | ================================================================= 3 | Description: Given a set of N rectangles, determines the area of 4 | it's union. 5 | 6 | Complexity: O(N^2) 7 | ----------------------------------------------------------------- 8 | Author: Gilbert Lee 9 | Date: Sept 8, 2002 10 | References: 11 | ----------------------------------------------------------------- 12 | Reliability: 1 successful use (Spain Problem 688) Sept 2002 13 | Notes: Scan line technique - For each y-line, it determines 14 | how much is inside the polygon, thus computing area 15 | in rectangular blocks 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #define MAXN 200 22 | 23 | typedef struct{ 24 | double minx, miny, maxx, maxy; 25 | } Rect; 26 | 27 | typedef struct{ 28 | double x, miny, maxy; 29 | char m; 30 | } Edge; 31 | 32 | Rect r[MAXN]; 33 | double ys[2*MAXN]; 34 | Edge e[2*MAXN]; 35 | 36 | int cmp_double(double *a, double *b){ 37 | return *a < *b ? -1 : *a > *b ? 1 : 0; 38 | } 39 | 40 | int cmp_edge(Edge *a, Edge *b){ 41 | return a->x < b->x ? -1 : a->x > b->x ? 1 : 0; 42 | } 43 | 44 | double area_unionrect(int n){ 45 | int flag, i, j; 46 | double curr, sum, sx; 47 | 48 | for(i = 0; i < n; i++){ 49 | e[2*i].miny = e[2*i+1].miny = ys[2*i] = r[i].miny; 50 | e[2*i].maxy = e[2*i+1].maxy = ys[2*i+1] = r[i].maxy; 51 | e[2*i].x = r[i].minx; 52 | e[2*i].m = 1; 53 | e[2*i+1].x = r[i].maxx; 54 | e[2*i+1].m = -1; 55 | } 56 | 57 | qsort(ys, 2*n, sizeof(ys[0]), (void *)cmp_double); 58 | qsort(e, 2*n, sizeof(e[0]), (void *)cmp_edge); 59 | 60 | sum = 0; 61 | for(i = 0; i < 2*n; i++){ 62 | if(i) sum += (ys[i]-ys[i-1])*curr; 63 | curr = flag = 0; 64 | for(j = 0; j < 2*n; j++){ 65 | if(e[j].miny <= ys[i] && ys[i] < e[j].maxy){ 66 | if(!flag) sx = e[j].x; 67 | flag += e[j].m; 68 | if(!flag) curr += e[j].x-sx; 69 | } 70 | } 71 | } 72 | return sum; 73 | } 74 | 75 | int main(){ 76 | int i, n; 77 | 78 | while(scanf("%d", &n) == 1){ 79 | for(i = 0; i < n; i++){ 80 | scanf("%lf %lf %lf %lf", 81 | &r[i].minx, &r[i].miny, &r[i].maxx, &r[i].maxy); 82 | } 83 | printf("Area of union is %f\n", area_unionrect(n)); 84 | } 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /graph/min_span_tree2.c: -------------------------------------------------------------------------------- 1 | /* Graph Theory: Minimum Spanning Tree (version 2) 2 | ================================================================= 3 | Description: Returns the edges / weight of the minimum spanning 4 | tree, given the graph in terms of edges. 5 | 6 | Vertices are numbered 0..N-1. 7 | 8 | Complexity: O(M lg M) where M is the number of edges 9 | ----------------------------------------------------------------- 10 | Author: Gilbert Lee 11 | Date: Dec 06, 2002 12 | References: 13 | ----------------------------------------------------------------- 14 | Reliability: 1 (Spain 10034) 15 | Notes: 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define MAXN 1000 24 | #define MAXM 1000000 25 | #define EPS 1e-8 26 | int n; 27 | 28 | typedef struct{ 29 | int u, v; /* Edge between u, v with weight w */ 30 | double w; 31 | } Edge; 32 | 33 | int sets[MAXN]; 34 | Edge edge[MAXM], treeedge[MAXN]; 35 | int numedge; 36 | 37 | int cmp_Edge(Edge *a, Edge *b){ 38 | if(fabs(a->w-b->w) < EPS) return 0; 39 | if(a->w < b->w) return -1; 40 | return 1; 41 | } 42 | 43 | int getRoot(int x){ 44 | if(sets[x] < 0) return x; 45 | return sets[x] = getRoot(sets[x]); 46 | } 47 | 48 | void Union(int a, int b){ 49 | int ra = getRoot(a); 50 | int rb = getRoot(b); 51 | if(ra != rb){ 52 | sets[ra] += sets[rb]; 53 | sets[rb] = ra; 54 | } 55 | } 56 | 57 | double mintree(){ 58 | double weight = 0.0; 59 | int i, count; 60 | 61 | qsort(edge, numedge, sizeof(edge[0]), (void *)cmp_Edge); 62 | for(i = count = 0; count < n-1; i++){ 63 | if(getRoot(edge[i].u) != getRoot(edge[i].v)){ 64 | Union(edge[i].u, edge[i].v); 65 | weight += edge[i].w; 66 | treeedge[count++] = edge[i]; 67 | } 68 | } 69 | return weight; 70 | } 71 | 72 | int main(){ 73 | int i; 74 | double weight; 75 | 76 | while(scanf("%d %d", &n, &numedge) == 2){ 77 | memset(sets, -1, sizeof(sets)); 78 | for(i = 0; i < numedge; i++){ 79 | scanf("%d %d %lf", &edge[i].u, &edge[i].v, &edge[i].w); 80 | } 81 | weight = mintree(); 82 | printf("Minimum cost tree = %f\n", weight); 83 | printf("Tree edges: \n"); 84 | for(i = 0; i < n-1; i++){ 85 | printf("%d %d %f\n", treeedge[i].u, treeedge[i].v, treeedge[i].w); 86 | } 87 | } 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /c++/pqueue.cc: -------------------------------------------------------------------------------- 1 | /* C++: Priority Queue template 2 | ================================================================= 3 | Description: Template for using C++ STL priority queues 4 | 5 | Given an adjacency matrix of a weighted graph, and 6 | a source vertex s, finds the shortest path from 7 | source to all other vertices and stores it in dist[] 8 | 9 | Complexity: lg(N) access time, where N is size of queue 10 | ----------------------------------------------------------------- 11 | Author: Gilbert Lee 12 | Date: Jan 31, 2003 13 | References: 14 | ----------------------------------------------------------------- 15 | Reliability: 0 16 | Notes: q.top() returns the LARGEST element in the queue, 17 | as defined by the < operator 18 | -> if X < Y, then Y is first on the queue 19 | q.pop() removes the largest element of the queue 20 | q.push(X) adds X onto the queue 21 | q.empty() returns 1 if queue is empty, 0 otherwise 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | using namespace std; 28 | 29 | #define MAXN 300 30 | int adj[MAXN][MAXN]; 31 | int dist[MAXN]; 32 | 33 | struct Node{ 34 | int node, cost; 35 | 36 | // i.e Node o is higher up in priority in the queue 37 | bool operator<(Node const &o) const { 38 | return cost > o.cost; 39 | } 40 | }; 41 | 42 | int main(){ 43 | int n, i, j; Node start, curr, next; 44 | 45 | while(scanf("%d", &n) == 1){ // Read # of vertices 46 | for(i = 0; i < n; i++) // Read adjacency matrix 47 | for(j = 0; j < n; j++) 48 | scanf("%d", &adj[i][j]); 49 | scanf("%d", &start.node); // Get source vertex 50 | start.cost = 0; 51 | memset(dist, -1, sizeof(dist)); // Initialize distance 52 | 53 | priority_queue q; // Initialize queue 54 | q.push(start); 55 | while(!q.empty()){ 56 | curr = q.top(); 57 | q.pop(); 58 | if(dist[curr.node] == -1){ 59 | dist[curr.node] = curr.cost; 60 | for(i = 0; i < n; i++){ 61 | if(dist[i] != -1 || adj[curr.node][i] == -1) continue; 62 | next.node = i; 63 | next.cost = curr.cost + adj[curr.node][i]; 64 | q.push(next); 65 | } 66 | } 67 | } 68 | for(i = 0; i < n; i++) 69 | printf("Distance from %d to %d: %d\n", start.node, i, dist[i]); 70 | } 71 | return 0; 72 | } 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /graph/strong_conn.cc: -------------------------------------------------------------------------------- 1 | /* Graph Theory: Strongly Connected Components 2 | ================================================================= 3 | Description: Given a directed graph, decomposes the graph into 4 | its strongly connected components. 5 | 6 | The components are returned in the vector of 7 | vector of ints scc. 8 | 9 | Complexity: O(V+E) 10 | ----------------------------------------------------------------- 11 | Author: Gilbert Lee 12 | Date: Feb 20, 2003 13 | References: 14 | ----------------------------------------------------------------- 15 | Reliability: 0 16 | Notes: Nodes are assumed to be labelled 0..n-1 17 | - This routine works by finding the earliest node 18 | reachable in the DFS tree. If the earliest such 19 | node is itself, then everything after it in the 20 | DFS tree is a strongly connected component. 21 | */ 22 | 23 | #include 24 | #include 25 | using namespace std; 26 | 27 | #define VI vector 28 | #define MAXN 1000 29 | 30 | VI g[MAXN], curr; 31 | vector< VI > scc; 32 | int dfsnum[MAXN], low[MAXN], id; 33 | char done[MAXN]; 34 | 35 | void visit(int x){ 36 | curr.push_back(x); 37 | dfsnum[x] = low[x] = id++; 38 | for(size_t i = 0; i < g[x].size(); i++) 39 | if(dfsnum[g[x][i]] == -1){ 40 | visit(g[x][i]); 41 | low[x] = min(low[x], low[g[x][i]]); 42 | } else if(!done[g[x][i]]) 43 | low[x] = min(low[x], dfsnum[g[x][i]]); 44 | 45 | if(low[x] == dfsnum[x]){ 46 | VI c; int y; 47 | do{ 48 | done[y = curr[curr.size()-1]] = 1; 49 | c.push_back(y); 50 | curr.pop_back(); 51 | } while(y != x); 52 | scc.push_back(c); 53 | } 54 | } 55 | 56 | void strong_conn(int n){ 57 | memset(dfsnum, -1, n*sizeof(int)); 58 | memset(done, 0, sizeof(done)); 59 | scc.clear(); curr.clear(); 60 | for(int i = id = 0; i < n; i++) 61 | if(dfsnum[i] == -1) visit(i); 62 | } 63 | 64 | int main(){ 65 | int n, m, i, x, y; 66 | 67 | while(scanf("%d %d", &n, &m) == 2){ 68 | for(i = 0; i < n; i++) g[i].clear(); 69 | for(i = 0; i < m; i++){ 70 | scanf("%d %d", &x, &y); 71 | g[x].push_back(y); 72 | } 73 | strong_conn(n); 74 | for(size_t i = 0; i < scc.size(); i++){ 75 | printf("Component %d:", i+1); 76 | for(size_t j = 0; j < scc[i].size(); j++) 77 | printf(" %d", scc[i][j]); 78 | printf("\n"); 79 | } 80 | } 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /graph/dijkstra/dijkstra.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | // Simple adjacency list graph implementation. 12 | 13 | struct Edge { 14 | Edge() : dst(0), len(0) {} 15 | Edge(int dst, int len) : dst(dst), len(len) {} 16 | int dst, len; 17 | }; 18 | 19 | // Typedefs for later readability. 20 | typedef list EdgeList; 21 | typedef vector AdjGraph; 22 | typedef vector::iterator NodeIterator; 23 | typedef vector::const_iterator ConstNodeIterator; 24 | typedef EdgeList::iterator EdgeIterator; 25 | typedef EdgeList::const_iterator ConstEdgeIterator; 26 | 27 | // Basic graph class. 28 | struct Graph { 29 | Graph(int N) : graph(N, list()) {} 30 | void addEdge(int src, int dst, int len) 31 | { 32 | graph[src].push_back(Edge(dst, len)); 33 | } 34 | AdjGraph graph; 35 | }; 36 | 37 | vector Dijkstra(const Graph& G, int src) 38 | { 39 | vector visited(G.graph.size(), false); 40 | vector distance(G.graph.size(), numeric_limits::max()); 41 | vector prev(G.graph.size(), -1); 42 | // Long template parameter list to make this a min-first priority queue 43 | priority_queue, vector >, greater > > q; 44 | 45 | // Add the source node with distance 0 to start. 46 | distance[src] = 0; 47 | q.push(make_pair(0, src)); 48 | 49 | while (!q.empty()) { 50 | // Look at the next node on the queue. 51 | pair entry = q.top(); q.pop(); 52 | // Cur is the node index. 53 | int cur = entry.second; 54 | // If we visited this node by some other route, that other route is better than or 55 | // equal to the current route, so we can skip it. 56 | if (visited[cur]) continue; 57 | // For each neighbour of this node . . . 58 | for (ConstEdgeIterator it = G.graph[cur].begin(); it != G.graph[cur].end(); ++it) { 59 | if (visited[it->dst]) continue; // Skip it if we've seen it. 60 | // If following this edge improves the shortest path . . . 61 | if (distance[cur] + it->len < distance[it->dst]) { 62 | // Update shortest path info, and enqueue node. 63 | distance[it->dst] = distance[cur] + it->len; 64 | prev[it->dst] = cur; 65 | q.push(make_pair(distance[it->dst], it->dst)); 66 | } 67 | } 68 | visited[cur] = true; 69 | } 70 | // Return vector of parents in the SSSP tree. 71 | return prev; 72 | } 73 | -------------------------------------------------------------------------------- /dynamic/long_common_subseq.c: -------------------------------------------------------------------------------- 1 | /* Dynamic Programming: Longest Common Subsequence 2 | ================================================================= 3 | Description: Given two arrays A and B with sizes n and m 4 | respectively, compute the length of the longest 5 | common subsequence. This routine also returns in 6 | the array 's' a longest common subsequence (it 7 | may not be unique). One can specify which one to 8 | choose when multiply longest common subsequences 9 | exist. 10 | 11 | Complexity: O(N*M) 12 | ----------------------------------------------------------------- 13 | Author: Howard Cheng, Gilbert Lee 14 | Date: Nov 19, 2002 15 | References: www.ics.uci.edu/~eppstein/161/960229.html 16 | ----------------------------------------------------------------- 17 | Reliability: 2 (Spanish Problem 10405, 10066) Dec 2002 18 | Notes: - Added way to change type of array 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | #define MAXN 20 25 | #define Atype int 26 | #define max(x,y) (((x)>(y))?(x):(y)) 27 | 28 | int LCS(Atype *A, int n, Atype *B, int m, Atype *s) 29 | { 30 | int L[MAXN+1][MAXN+1]; 31 | int i, j, k; 32 | 33 | for(i = n; i >= 0; i--) for(j = m; j >= 0; j--){ 34 | if(i == n || j == m){ 35 | L[i][j] = 0; 36 | } else if(A[i] == B[j]){ 37 | L[i][j] = 1 + L[i+1][j+1]; 38 | } else { 39 | L[i][j] = max(L[i+1][j], L[i][j+1]); 40 | } 41 | } 42 | 43 | /* The following is not needed if you are not interested in 44 | a longest common subsequence */ 45 | 46 | k = 0; 47 | i = j = 0; 48 | while(i < n && j < m){ 49 | if(A[i] == B[j]){ 50 | s[k++] = A[i++]; 51 | j++; 52 | } else if(L[i+1][j] > L[i][j+1]){ 53 | i++; 54 | } else if(L[i+1][j] < L[i][j+1]){ 55 | j++; 56 | } else { 57 | /* put tie-breaking conditions here */ 58 | 59 | /* eg. pick the one that starts at the first one the earliest */ 60 | j++; 61 | } 62 | } 63 | return L[0][0]; 64 | } 65 | 66 | int main(void) 67 | { 68 | Atype A[MAXN], B[MAXN], s[MAXN]; 69 | int m, n, i, l; 70 | 71 | while (scanf("%d %d", &n, &m) == 2 && 1 <= n && 1 <= m && 72 | n <= MAXN && m <= MAXN) { 73 | for (i = 0; i < n; i++) scanf("%d", &A[i]); 74 | for (i = 0; i < m; i++) scanf("%d", &B[i]); 75 | l = LCS(A, n, B, m, s); 76 | for (i = 0; i < l; i++) printf("%d ", s[i]); 77 | printf("\nLen = %d\n", l); 78 | } 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /Search/binsearch.c: -------------------------------------------------------------------------------- 1 | /* Search: Binary Search Template 2 | ================================================================= 3 | Description: Given a sorted array A of size n, it tried to find 4 | an item x in the array using binary search. The 5 | function returns non-zero if x is found, and zero 6 | otherwise. Furthermore, if it is found, then 7 | A[index] = x. If it is not found, then index is the 8 | place x should be inserted into A. 9 | 10 | ie. A[i] <= x for 0 <= i < index 11 | x < A[i] for index <= i < n 12 | 13 | There is also an insert routine here that will 14 | insert the element into the right place after the 15 | array has been reallocated (if necessary) to 16 | store n+1 elements 17 | 18 | Complexity: 19 | ----------------------------------------------------------------- 20 | Author: Howard Cheng 21 | Date: Nov 10, 2003 22 | References: 23 | ----------------------------------------------------------------- 24 | Reliability: 0 25 | Notes: This routine is written for integer arrays, but can 26 | be adapted to other types by changing the 27 | comparison operator. 28 | */ 29 | 30 | #include 31 | 32 | int bin_search(int *A, int n, int x, int *index){ 33 | int low, up, mid; 34 | 35 | if (n <= 0 || x < A[0]) { 36 | *index = 0; 37 | return 0; 38 | } 39 | if (A[n-1] < x) { 40 | *index = n; 41 | return 0; 42 | } 43 | if (x == A[n-1]) { 44 | *index = n-1; 45 | return 1; 46 | } 47 | for(low = 0, up = n-1; low + 1 < up;){ 48 | mid = (low+up)/2; 49 | if (A[mid] <= x) 50 | low = mid; 51 | else 52 | up = mid; 53 | } 54 | if (A[low] == x) { 55 | *index = low; 56 | return 1; 57 | } else { 58 | *index = up; 59 | return 0; 60 | } 61 | } 62 | 63 | void insert(int *A, int n, int x, int index){ 64 | int i; 65 | for (i = n-1; i >= index+1; i--) 66 | A[i] = A[i-1]; 67 | A[index] = x; 68 | } 69 | 70 | 71 | int main(void){ 72 | int A[10000]; 73 | int n, i, x, index; 74 | 75 | n = 0; 76 | while (scanf("%d", &x) == 1 && n < 10000) { 77 | if (!bin_search(A, n, x, &index)) { 78 | n++; 79 | insert(A, n, x, index); 80 | } 81 | printf("List:"); 82 | for (i = 0; i < n; i++) { 83 | printf(" %d", A[i]); 84 | if (i == index) printf("*"); 85 | } 86 | printf("\n"); 87 | } 88 | return 0; 89 | } 90 | --------------------------------------------------------------------------------