├── .DS_Store ├── Competitive Programming 3.pdf ├── Junior-Training-Sheet-template-V5.6.xlsx ├── README.md ├── analisisAlgoritmos.pdf ├── ch1 ├── a.out ├── ejer1.c ├── ejer2.c ├── ejer3.c ├── ejer4.c ├── ejer5.c ├── ejer6.c └── helloworld.c └── cpbook-code ├── .gitignore ├── README.md ├── ch1 ├── Ex_1.3.4.1 │ ├── task01.java │ ├── task02.cpp │ ├── task02.ml │ ├── task02.py │ ├── task03.java │ ├── task03.py │ ├── task04.cpp │ ├── task04.ml │ ├── task04.py │ ├── task05.cpp │ ├── task05.ml │ ├── task05.py │ ├── task06.cpp │ ├── task06.ml │ ├── task06.py │ ├── task07.cpp │ ├── task07.ml │ ├── task07.py │ ├── task08.cpp │ ├── task08.ml │ ├── task08.py │ ├── task09.java │ ├── task10.java │ ├── task11.java │ ├── task12.java │ └── task12.py ├── IO.cpp ├── IO.java ├── IO.ml ├── IO.py ├── IO_in1.txt ├── IO_in2.txt ├── IO_in3.txt ├── IO_in4.txt ├── IO_in5.txt ├── UVa11616.cpp ├── UVa11616.java ├── UVa11616.ml ├── UVa11616.py ├── basic_string.cpp ├── basic_string.html ├── basic_string.java ├── basic_string.ml ├── basic_string.py ├── basic_string_in.txt ├── basic_string_out.txt ├── factorial.java ├── factorial.py ├── moscowdream.cpp ├── moscowdream.java ├── moscowdream.ml ├── moscowdream.py ├── scanf.cpp ├── scanf.ml ├── scanf_in.txt └── zip.py ├── ch2 ├── lineards │ ├── UVa10925.java │ ├── UVa10925.py │ ├── array_algorithms.cpp │ ├── array_algorithms.java │ ├── array_algorithms.py │ ├── bit_manipulation.cpp │ ├── bit_manipulation.java │ ├── bit_manipulation.ml │ ├── bit_manipulation.py │ ├── list.cpp │ ├── list.java │ ├── list.ml │ ├── list.py │ ├── resizeable_array.cpp │ ├── resizeable_array.java │ └── resizeable_array.py ├── nonlineards │ ├── AVL.cpp │ ├── AVL.java │ ├── QuickSelect.cpp │ ├── QuickSelect.java │ ├── QuickSelect.ml │ ├── QuickSelect.py │ ├── map_set.cpp │ ├── map_set.java │ ├── map_set.ml │ ├── pbds.cpp │ ├── priority_queue.cpp │ ├── priority_queue.java │ ├── priority_queue.ml │ ├── priority_queue.py │ ├── unordered_map_unordered_set.cpp │ ├── unordered_map_unordered_set.java │ ├── unordered_map_unordered_set.ml │ └── unordered_map_unordered_set.py └── ourown │ ├── IntegerPair.java │ ├── IntegerTriple.java │ ├── fenwicktree_ds.cpp │ ├── fenwicktree_ds.java │ ├── fenwicktree_ds.ml │ ├── fenwicktree_ds.py │ ├── graph_ds.cpp │ ├── graph_ds.java │ ├── graph_ds.ml │ ├── graph_ds.py │ ├── graph_ds.txt │ ├── segmenttree_ds.cpp │ ├── segmenttree_ds.java │ ├── segmenttree_ds.ml │ ├── segmenttree_ds.py │ ├── unionfind_ds.cpp │ ├── unionfind_ds.java │ ├── unionfind_ds.ml │ └── unionfind_ds.py ├── ch3 ├── cs │ ├── UVa00441.cpp │ ├── UVa00441.java │ ├── UVa00441.ml │ ├── UVa00441.py │ ├── UVa00725.cpp │ ├── UVa00725.java │ ├── UVa00725.ml │ ├── UVa00725.py │ ├── UVa00750.cpp │ ├── UVa00750.java │ ├── UVa00750.ml │ ├── UVa00750.py │ ├── UVa11565.cpp │ ├── UVa11565.java │ ├── UVa11565.ml │ ├── UVa11565.py │ ├── UVa11742.cpp │ ├── UVa11742.java │ ├── UVa11742.ml │ ├── UVa11742.py │ ├── UVa12455.cpp │ ├── UVa12455.java │ ├── UVa12455.ml │ ├── UVa12455.py │ ├── itertools1.py │ └── itertools2.py ├── dnc │ ├── IntegerPair.java │ ├── UVa11935.cpp │ ├── UVa11935.java │ ├── UVa11935.ml │ ├── UVa11935.py │ ├── tricktreat.cpp │ ├── tricktreat.java │ ├── tricktreat.ml │ └── tricktreat.py ├── dp │ ├── LIS.cpp │ ├── LIS.java │ ├── LIS.ml │ ├── LIS.py │ ├── Max1DRangeSum.cpp │ ├── Max1DRangeSum.java │ ├── Max1DRangeSum.ml │ ├── Max1DRangeSum.py │ ├── UVa00108.cpp │ ├── UVa00108.java │ ├── UVa00108.ml │ ├── UVa00108.py │ ├── UVa00674.cpp │ ├── UVa00674.java │ ├── UVa00674.ml │ ├── UVa00674.py │ ├── UVa10003.cpp │ ├── UVa10003.java │ ├── UVa10003.ml │ ├── UVa10003.py │ ├── UVa10003_TLE.py │ ├── UVa10003_knuth_bu.cpp │ ├── UVa10003_knuth_td.cpp │ ├── UVa10130.cpp │ ├── UVa10130.java │ ├── UVa10130.ml │ ├── UVa10130.py │ ├── UVa10943.cpp │ ├── UVa10943.java │ ├── UVa10943.ml │ ├── UVa10943.py │ ├── UVa11450_bu.cpp │ ├── UVa11450_bu.java │ ├── UVa11450_bu.ml │ ├── UVa11450_bu.py │ ├── UVa11450_td.cpp │ ├── UVa11450_td.java │ ├── UVa11450_td.ml │ ├── UVa11450_td.py │ ├── beepers_UVa10496.cpp │ ├── beepers_UVa10496.java │ ├── beepers_UVa10496.ml │ └── beepers_UVa10496.py └── greedy │ ├── ballotboxes_UVa12390.cpp │ ├── ballotboxes_UVa12390_TLE.java │ ├── ballotboxes_UVa12390_TLE.py │ ├── ballotboxes_UVa12390_bsta.py │ ├── grass_UVa10382.cpp │ ├── grass_UVa10382.java │ ├── grass_UVa10382.py │ ├── in.txt │ ├── loowater_UVa11292.cpp │ ├── loowater_UVa11292.java │ ├── loowater_UVa11292.ml │ └── loowater_UVa11292.py ├── ch4 ├── IntegerPair.java ├── IntegerTriple.java ├── floyd_warshall.cpp ├── floyd_warshall.java ├── floyd_warshall.ml ├── floyd_warshall.py ├── floyd_warshall_in.txt ├── hierholzer.cpp ├── hierholzer.java ├── hierholzer.ml ├── hierholzer.py ├── mcbm.cpp ├── mcbm.java ├── mcbm.ml ├── mcbm.py ├── mst │ ├── IntegerPair.java │ ├── IntegerTriple.java │ ├── kruskal.cpp │ ├── kruskal.java │ ├── kruskal.ml │ ├── kruskal.py │ ├── mst_in.txt │ ├── prim.cpp │ ├── prim.java │ ├── prim.ml │ └── prim.py ├── sssp │ ├── IntegerPair.java │ ├── bellman_ford.cpp │ ├── bellman_ford.java │ ├── bellman_ford.ml │ ├── bellman_ford.py │ ├── bellman_ford_in.txt │ ├── bellman_ford_moore.cpp │ ├── bellman_ford_moore.java │ ├── bellman_ford_moore.ml │ ├── bellman_ford_moore.py │ ├── bfs.cpp │ ├── bfs.java │ ├── bfs.ml │ ├── bfs.py │ ├── bfs_in.txt │ ├── dijkstra.cpp │ ├── dijkstra.java │ ├── dijkstra.ml │ ├── dijkstra.py │ └── dijkstra_in.txt └── traversal │ ├── IntegerPair.java │ ├── UVa00469.cpp │ ├── UVa00469.java │ ├── UVa00469.ml │ ├── UVa00469.py │ ├── UVa10004.cpp │ ├── UVa10004.java │ ├── UVa10004.ml │ ├── UVa10004.py │ ├── UVa11060.cpp │ ├── UVa11060.java │ ├── UVa11060.ml │ ├── UVa11060.py │ ├── UVa11838.cpp │ ├── UVa11838.java │ ├── UVa11838.ml │ ├── UVa11838.py │ ├── articulation.cpp │ ├── articulation.java │ ├── articulation.ml │ ├── articulation.py │ ├── articulation_in.txt │ ├── cyclecheck.cpp │ ├── cyclecheck.java │ ├── cyclecheck.ml │ ├── cyclecheck.py │ ├── dfs_cc.cpp │ ├── dfs_cc.java │ ├── dfs_cc.ml │ ├── dfs_cc.py │ ├── dfs_cc_in.txt │ ├── scc_in.txt │ ├── toposort.cpp │ ├── toposort.java │ ├── toposort.ml │ ├── toposort.py │ └── toposort_in.txt ├── ch5 ├── UVa00350.cpp ├── UVa00350.java ├── UVa00350.ml ├── UVa00350.py ├── UVa01230.cpp ├── UVa01230.java ├── UVa01230.py ├── UVa10229.cpp ├── UVa10229.java ├── UVa10229.ml ├── UVa10229.py ├── UVa10235.java ├── UVa10814.java ├── UVa10814.py ├── basicremains_UVa10551.java ├── combinatorics.cpp ├── combinatorics.java ├── combinatorics.py ├── factovisors_UVa10139.cpp ├── factovisors_UVa10139.java ├── factovisors_UVa10139.py ├── modInverse.cpp ├── modInverse.java ├── modInverse.py ├── primes.cpp ├── primes.java ├── primes.ml └── primes.py ├── ch6 ├── Trie.cpp ├── Trie.java ├── Trie.py ├── sa_lcp.cpp ├── sa_lcp.java ├── sa_lcp.ml ├── sa_lcp.py ├── sa_lcp_in.txt ├── sa_lcp_slow.cpp ├── string_alignment.cpp ├── string_alignment.java ├── string_alignment.ml ├── string_alignment.py ├── string_matching.cpp ├── string_matching.java ├── string_matching.ml ├── string_matching.py └── trie.ml ├── ch7 ├── UVa11817.cpp ├── UVa11817.java ├── UVa11817.py ├── circles.cpp ├── circles.java ├── circles.ml ├── circles.py ├── points_lines.cpp ├── points_lines.java ├── points_lines.ml ├── points_lines.py ├── polygon.cpp ├── polygon.java ├── polygon.ml ├── polygon.py ├── triangles.cpp ├── triangles.java ├── triangles.ml └── triangles.py ├── ch8 ├── UVa01079.cpp ├── UVa01079.java ├── UVa01079.ml ├── UVa01099.cpp ├── UVa01099.ml ├── UVa01231.cpp ├── UVa01231.java ├── UVa01231.ml ├── UVa01231.py ├── UVa01238.cpp ├── UVa01238.java ├── UVa01238.ml ├── UVa01238.py ├── UVa10243.cpp ├── UVa10243.py ├── UVa10243_TLE.java ├── UVa10911.cpp ├── UVa10911.java ├── UVa10911.ml ├── UVa10911.py ├── UVa11065.cpp ├── UVa11065.java ├── UVa11065.ml ├── UVa11195.cpp ├── UVa11195.ml ├── UVa11212.cpp ├── UVa11212.ml ├── UVa11212_alt.cpp ├── UVa11646.cpp ├── UVa11646.java ├── UVa11646.py ├── maxflow.cpp ├── maxflow.java ├── maxflow.ml ├── maxflow.py └── maxflow_in.txt └── ch9 ├── GaussianElimination.cpp ├── GaussianElimination.java ├── GaussianElimination.ml ├── GaussianElimination.py ├── HLD.cpp ├── HLD.java ├── HLD.ml ├── HLD.py ├── LCA.cpp ├── LCA.java ├── LCA.ml ├── LCA.py ├── Pollardsrho.java ├── Pollardsrho.ml ├── SparseTable.cpp ├── SparseTable.java ├── SparseTable.ml ├── SparseTable.py ├── UVa10181.cpp ├── UVa10181.java ├── heliocentric.cpp ├── heliocentric.java ├── heliocentric.ml ├── heliocentric.py ├── mcmf.cpp ├── mcmf.py └── mcmf_in.txt /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adsoftsito/competitive_programming/8dd49b411a81f406f774c0043e8bc9cdd15425f6/.DS_Store -------------------------------------------------------------------------------- /Competitive Programming 3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adsoftsito/competitive_programming/8dd49b411a81f406f774c0043e8bc9cdd15425f6/Competitive Programming 3.pdf -------------------------------------------------------------------------------- /Junior-Training-Sheet-template-V5.6.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adsoftsito/competitive_programming/8dd49b411a81f406f774c0043e8bc9cdd15425f6/Junior-Training-Sheet-template-V5.6.xlsx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Welcome to Competitive Programming Club 2 | 3 | 1. Download competitive programming book 4 | 2. Download Junior Trainning Template excel 5 | 3. Enter to club [team](https://docs.google.com/spreadsheets/d/1c7JFa8pFZIxwEcXBxeDZT8foNpuYkmjV3aP9ss_91ts/edit?usp=sharing) 6 | 7 | # Session 1 8 | [Slides 1](https://docs.google.com/presentation/d/1rpNoqcZLTZy481P7jhzwmVMlky9b8QiW/edit?usp=sharing&ouid=112454259737266877874&rtpof=true&sd=true) 9 | 10 | # Session 2 11 | [Slides 2](https://docs.google.com/presentation/d/1hbJRfII9Z_9ueiPMnIWz7j0DJ4JY1xk7/edit?usp=sharing&ouid=112454259737266877874&rtpof=true&sd=true) 12 | 13 | # Session 3 14 | [Slides 3](https://docs.google.com/presentation/d/1Rs7ufmnrbMhTvx15BTetqWUn3JqAcBze/edit?usp=sharing&ouid=112454259737266877874&rtpof=true&sd=true) 15 | -------------------------------------------------------------------------------- /analisisAlgoritmos.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adsoftsito/competitive_programming/8dd49b411a81f406f774c0043e8bc9cdd15425f6/analisisAlgoritmos.pdf -------------------------------------------------------------------------------- /ch1/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adsoftsito/competitive_programming/8dd49b411a81f406f774c0043e8bc9cdd15425f6/ch1/a.out -------------------------------------------------------------------------------- /ch1/ejer1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | int TC, a, b; 6 | scanf("%d", &TC); // number of test cases 7 | while(TC--) { // shortcut to repeat until 0 8 | scanf("%d %d", &a, &b); // compute answer 9 | printf("%d \n", a+b); // on the fly 10 | } 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /ch1/ejer2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | int a, b; 6 | // stop when both integers are 0 7 | while(scanf("%d %d", &a, &b), (a || b)) 8 | printf("%d \n", a+b); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /ch1/ejer3.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | int a, b; 6 | // scanf returns the number of items read 7 | while(scanf("%d %d", &a, &b) == 2) 8 | printf("%d \n", a+b); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /ch1/ejer4.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | int a, b, c = 1; 6 | while(scanf("%d %d", &a, &b) != EOF) 7 | // notice the two \n 8 | printf("Case %d: %d\n\n",c++, a+b); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /ch1/ejer5.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | int a, b, c = 1; 6 | while(scanf("%d %d", &a, &b) != EOF) { 7 | if (c>1) printf("\n"); // 2nd/more cases 8 | printf("Case %d: %d\n\n",c++, a+b); 9 | } 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /ch1/ejer6.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | int k, ans, v; 6 | while(scanf("%d", &k) != EOF) { 7 | ans = 0; 8 | while(k--) { 9 | scanf("%d", &v); 10 | ans += v; 11 | } 12 | printf("%d\n", ans); 13 | } 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ch1/helloworld.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | printf("hello acm world !"); 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /cpbook-code/.gitignore: -------------------------------------------------------------------------------- 1 | *.aux 2 | *.bak 3 | *.log 4 | *.ind 5 | *.bbl 6 | *.sav 7 | *.blg 8 | *.idx 9 | *.out 10 | *.ilg 11 | *.exe 12 | *.class 13 | *.stackdump 14 | 15 | __pycache__/ 16 | -------------------------------------------------------------------------------- /cpbook-code/README.md: -------------------------------------------------------------------------------- 1 | # cpbook-code 2 | CP4 Free Source Code Project (cpp/gnu++17, java/java11, py/python3, and ml/ocaml). 3 | 4 | This repo is expected to be much more up-to-date than CP4 itself, that will go out to public on 19 July 2020. 5 | 6 | All code in this repo are mostly (reasonably good, hopefully :) implementation of many well-known data structures and algorithms, 7 | so you are free to copy, adapt, use the code (in your next programming contest or any other coding project). 8 | 9 | Note to Computer Science educators worldwide: please include all the code discussed here in your plagiarism checker system as "excluded". 10 | Please do NOT test your students to just (re-)code these basic data structures/algorithms verbatim as that is just reinventing the wheel. 11 | Please test them with higher order thinking questions/problems that use these code instead. 12 | 13 | We will be thankful if you cite us (Steven Halim, Felix Halim, Suhendry Effendy) when you use code in this repo. 14 | 15 | This license is probably the most suitable: https://opensource.org/licenses/UPL 16 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task01.java: -------------------------------------------------------------------------------- 1 | import java.util.*; // Java code for task 1 2 | class Main { 3 | public static void main(String[] args) { // Java has printf too! 4 | System.out.printf("%7.3f\n", new Scanner(System.in).nextDouble()); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task02.cpp: -------------------------------------------------------------------------------- 1 | #include // C++ code for task 2 2 | int main() { 3 | int n; scanf("%d", &n); 4 | printf("%.*lf\n", n, M_PI); // adjust field width 5 | } 6 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task02.ml: -------------------------------------------------------------------------------- 1 | open Scanf 2 | open Printf 3 | 4 | let () = 5 | let pi = 2. *. acos 0. in 6 | scanf "%d" (fun n -> printf "%.*f\n" n pi) 7 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task02.py: -------------------------------------------------------------------------------- 1 | from math import pi 2 | print(round(pi, int(input()))) 3 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task03.java: -------------------------------------------------------------------------------- 1 | import java.util.*; // Java code for task 3 2 | class Main { 3 | public static void main(String[] args) { 4 | String[] names = new String[] 5 | { "", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; 6 | Calendar that_day = new GregorianCalendar(2010, 7, 9); // 9 August 2010 7 | // note that month starts from 0, so we need to put 7 instead of 8 8 | System.out.println(names[that_day.get(Calendar.DAY_OF_WEEK)]); // "Mon" 9 | long today = new Date().getTime(); // today 10 | long diff = (today - that_day.getTime().getTime()) / (24*60*60*1000); 11 | System.out.println(diff + " day(s) ago"); // ans grows over time 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task03.py: -------------------------------------------------------------------------------- 1 | from datetime import date # Python code for task 3 2 | s = date(2010, 8, 9) # CP1 launch date 3 | t = date.today() 4 | print(s.strftime("%a")) # 'Mon', %A for 'Monday' 5 | print("{} day(s) ago".format((t-s).days)) # ans grows over time 6 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task04.cpp: -------------------------------------------------------------------------------- 1 | #include // C++ code for task 4 2 | using namespace std; 3 | #define ALL(x) x.begin(), x.end() 4 | #define UNIQUE(c) (c).resize(unique(ALL(c)) - (c).begin()) 5 | int main() { 6 | vector v = {1, 2, 2, 2, 3, 3, 2, 2, 1}; 7 | sort(ALL(v)); UNIQUE(v); 8 | for (auto &x : v) printf("%d\n", x); 9 | } 10 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task04.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | 3 | (* returns a list containing the unique elements of a sorted array *) 4 | let unique arr = 5 | Array.fold_right (fun elem xs -> 6 | if xs = [] || not (elem = List.hd xs) then elem :: xs else xs 7 | ) arr [] 8 | 9 | let () = 10 | let v = [| 1; 2; 2; 2; 3; 3; 2; 2; 1 |] in 11 | Array.sort compare v; 12 | List.iter (fun x -> printf "%d\n" x) (unique v) -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task04.py: -------------------------------------------------------------------------------- 1 | print(*sorted(set(input().split()), key=int), sep='\n') 2 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task05.cpp: -------------------------------------------------------------------------------- 1 | #include // C++ code for task 5 2 | using namespace std; 3 | typedef tuple iii; // use natural order 4 | int main() { 5 | multiset birthdays; // auto sorting :) 6 | birthdays.emplace(5, 24, -1980); // reorder DD/MM/YYYY 7 | birthdays.emplace(5, 24, -1982); // to MM, DD, and then 8 | birthdays.emplace(11, 13, -1983); // use NEGATIVE YYYY 9 | birthdays.emplace(5, 24, -1982); // duplicates allowed 10 | for (auto &[mm, dd, yyyy] : birthdays) // C++17 style 11 | printf("%d %d %d\n", dd, mm, -yyyy); 12 | } 13 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task05.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | 3 | let () = 4 | let a = (5, 24, -1982) in 5 | let b = (5, 24, -1980) in 6 | let c = (11, 13, -1983) in 7 | let birthdays = [| a; b; c |] in 8 | Array.sort compare birthdays; 9 | Array.iter (fun (m, d, y) -> 10 | printf "%d %d %d\n" d m (-y) 11 | ) birthdays 12 | 13 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task05.py: -------------------------------------------------------------------------------- 1 | a = (5, 24, -1982) # Python code for task 5 2 | b = (5, 24, -1980) 3 | c = (11, 13, -1983) 4 | s = sorted({c, a, b}) 5 | for i in s: 6 | print(f'{i[1]} {i[0]} {-i[2]}') 7 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task06.cpp: -------------------------------------------------------------------------------- 1 | #include // C++ code for task 6 2 | using namespace std; 3 | int main() { 4 | int n = 5, L[] = {10, 7, 5, 20, 8}, v = 7; 5 | sort(L, L+n); 6 | printf("%d\n", binary_search(L, L+n, v)); // should be index 1 7 | } 8 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task06.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | 3 | let rec binary_search arr lo hi x = 4 | if lo = hi then false 5 | else begin 6 | let mid = (lo + hi) / 2 in 7 | if arr.(mid) = x then true 8 | else if arr.(mid) > x then (binary_search arr lo mid x) 9 | else binary_search arr (mid+1) hi x 10 | end 11 | 12 | 13 | let () = 14 | let l = [| 10; 7; 5; 20; 8 |] in 15 | Array.sort compare l; 16 | printf "%B\n" (binary_search l 0 5 7) 17 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task06.py: -------------------------------------------------------------------------------- 1 | from bisect import bisect_left 2 | i = bisect_left(L, v) 3 | print(i != len(L) and L[i] == v) 4 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task07.cpp: -------------------------------------------------------------------------------- 1 | #include // C++ code for task 7 2 | using namespace std; 3 | int main() { 4 | string s = "ABCD"; // "ABCDEFGHIJ"; // change "ABCD" to "ABCDEFGHIJ" to match the actual problem (but it will take some time to print) 5 | do { 6 | for (int i = 0; i < (int)s.length(); ++i) printf("%c ", s[i]); 7 | printf("\n"); 8 | } 9 | while (next_permutation(s.begin(), s.end())); 10 | } 11 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task07.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | 3 | let remove_from x l = List.filter ((<>) x) l 4 | 5 | let rec permutations = function 6 | | [] -> [] 7 | | x::[] -> [[x]] 8 | | xs -> 9 | List.fold_left (fun acc x -> acc @ List.map (fun perm -> x::perm) (permutations (remove_from x xs))) [] xs 10 | 11 | let print xs = 12 | List.iter (fun x -> printf "%c " x) xs; 13 | printf "\n" 14 | 15 | let () = 16 | let open Char in 17 | let p = List.init 4 (fun x -> chr (code 'A' + x)) in (* change 4 to 10 to match the actual problem (but it will take some time to print) *) 18 | List.iter print (permutations p) 19 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task07.py: -------------------------------------------------------------------------------- 1 | from string import ascii_uppercase # overkill, we can just use "ABCDEFGHIJ" below 2 | from itertools import permutations 3 | print(*permutations(ascii_uppercase[:4]), sep='\n') # change 4 to 10 to match the actual problem (but it will take some time to print) 4 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task08.cpp: -------------------------------------------------------------------------------- 1 | #include // C++ code for task 8 2 | using namespace std; 3 | #define LSOne(S) ((S) & -(S)) // notice the brackets 4 | int main() { 5 | int N = 4; // change 4 to 20 to match the actual problem (but it will take some time to print) 6 | for (int i = 0; i < (1< 0 do 17 | let ls = ls_one !pos in 18 | pos := !pos - ls; 19 | printf "%d " (ctz ls) 20 | done; 21 | printf "\n" 22 | done -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task08.py: -------------------------------------------------------------------------------- 1 | from itertools import combinations 2 | m = range(1,n+1) 3 | print(*(list(combinations(m,i)) for i in m)) 4 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task09.java: -------------------------------------------------------------------------------- 1 | import java.math.*; // Java code for task 9 2 | class Main { 3 | public static void main(String[] args) { 4 | String str = "FF"; int X = 16, Y = 10; 5 | System.out.println(new BigInteger(str, X).toString(Y)); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task10.java: -------------------------------------------------------------------------------- 1 | class Main { // Java code for task 10 2 | public static void main(String[] args) { 3 | String S = "line: a70 and z72 will be replaced, aa24 and a872 won't"; 4 | System.out.println(S.replaceAll("\\b+[a-z][0-9][0-9]\\b+", "***")); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task11.java: -------------------------------------------------------------------------------- 1 | import java.math.*; // Java code for task 12 2 | class Main { 3 | public static void main(String[] args) throws Exception { 4 | BigInteger x = new BigInteger("48112959837082048697"); // Big Integer 5 | System.out.println(x.isProbablePrime(10) ? "Prime" : "Composite"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task12.java: -------------------------------------------------------------------------------- 1 | import java.util.*; // Java code for task 11 2 | import javax.script.*; 3 | class Main { 4 | public static void main(String[] args) throws Exception { 5 | ScriptEngineManager mgr = new ScriptEngineManager(); 6 | ScriptEngine engine = mgr.getEngineByName("JavaScript"); // "cheat" 7 | Scanner sc = new Scanner(System.in); 8 | while (sc.hasNextLine()) System.out.println(engine.eval(sc.nextLine())); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /cpbook-code/ch1/Ex_1.3.4.1/task12.py: -------------------------------------------------------------------------------- 1 | print(eval(input())) 2 | -------------------------------------------------------------------------------- /cpbook-code/ch1/IO.py: -------------------------------------------------------------------------------- 1 | # comment all lines and only uncomment demo code that you are interested with 2 | 3 | # IO_in1.txt 4 | import sys 5 | inputs = iter(sys.stdin.readlines()) 6 | TC = int(next(inputs)) 7 | for _ in range(TC): 8 | print(sum(map(int, next(inputs).split()))) 9 | 10 | # # IO_in2.txt 11 | # import sys 12 | # for line in sys.stdin.readlines(): 13 | # if line == '0 0\n': break 14 | # print(sum(map(int, line.split()))) 15 | 16 | # # IO_in3.txt 17 | # import sys 18 | # for line in sys.stdin.readlines(): 19 | # print(sum(map(int, line.split()))) 20 | 21 | # # IO_in3.txt, same input file as before 22 | # import sys 23 | # for c, line in enumerate(sys.stdin.readlines(), 1): 24 | # print("Case %s: %s\n" % (c, sum(map(int, line.split())))) 25 | 26 | # # IO_in3.txt, same input file as before 27 | # import sys 28 | # for c, line in enumerate(sys.stdin.readlines(), 1): 29 | # if c > 1: print() 30 | # print("Case %s: %s" % (c, sum(map(int, line.split())))) 31 | 32 | # # IO_in4.txt 33 | # import sys 34 | # for line in sys.stdin.readlines(): 35 | # print(sum(map(int, line.split()[1:]))) # skip the first integer 36 | 37 | # # IO_in5.txt 38 | # import sys 39 | # for line in sys.stdin.readlines(): 40 | # print(sum(map(int, line.split()))) 41 | -------------------------------------------------------------------------------- /cpbook-code/ch1/IO_in1.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 1 2 3 | 5 7 4 | 6 3 5 | -------------------------------------------------------------------------------- /cpbook-code/ch1/IO_in2.txt: -------------------------------------------------------------------------------- 1 | 1 2 2 | 5 7 3 | 6 3 4 | 0 0 5 | 1 1 6 | -------------------------------------------------------------------------------- /cpbook-code/ch1/IO_in3.txt: -------------------------------------------------------------------------------- 1 | 1 2 2 | 5 7 3 | 6 3 4 | -------------------------------------------------------------------------------- /cpbook-code/ch1/IO_in4.txt: -------------------------------------------------------------------------------- 1 | 1 1 2 | 2 3 4 3 | 3 8 1 1 4 | 4 7 2 9 3 5 | 5 1 1 1 1 1 6 | -------------------------------------------------------------------------------- /cpbook-code/ch1/IO_in5.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 3 4 3 | 8 1 1 4 | 7 2 9 3 5 | 1 1 1 1 1 6 | -------------------------------------------------------------------------------- /cpbook-code/ch1/UVa11616.cpp: -------------------------------------------------------------------------------- 1 | // Roman Numerals 2 | 3 | #include 4 | using namespace std; 5 | 6 | typedef pair is; 7 | 8 | void AtoR(int A) { // Arabic to Roman 9 | vector convert({ 10 | {1000,"M"}, {900,"CM"}, {500,"D"}, {400,"CD"}, {100,"C"}, {90,"XC"}, 11 | {50,"L"}, {40,"XL"}, {10,"X"}, {9,"IX"}, {5,"V"}, {4,"IV"}, {1,"I"} 12 | }); 13 | for (auto &[value, roman] : convert) // from large to small 14 | while (A >= value) { 15 | cout << roman; 16 | A -= value; 17 | } 18 | cout << "\n"; 19 | } 20 | 21 | int value(char letter) { 22 | switch (letter) { 23 | case 'I': return 1; 24 | case 'V': return 5; 25 | case 'X': return 10; 26 | case 'L': return 50; 27 | case 'C': return 100; 28 | case 'D': return 500; 29 | case 'M': return 1000; 30 | } 31 | return 0; 32 | } 33 | 34 | void RtoA(string R) { // Roman to Arabic 35 | int ans = 0; 36 | for (int i = 0; R[i]; ++i) 37 | if (R[i+1] && (value(R[i]) < value(R[i+1]))) { // check next char first 38 | ans += value(R[i+1])-value(R[i]); // by definition 39 | ++i; // skip this char 40 | } 41 | else 42 | ans += value(R[i]); 43 | cout << ans << "\n"; 44 | } 45 | 46 | int main() { 47 | string S; 48 | while (getline(cin, S)) { 49 | if (isdigit(S[0])) 50 | AtoR(stoi(S)); // Arabic to Roman Numerals 51 | else 52 | RtoA(S); // Roman to Arabic Numerals 53 | } 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /cpbook-code/ch1/UVa11616.ml: -------------------------------------------------------------------------------- 1 | (* Roman Numerals *) 2 | 3 | open Printf 4 | open Scanf 5 | 6 | module CMap = Map.Make (struct 7 | type t = char 8 | let compare = compare 9 | end) 10 | 11 | let ator a = 12 | let cvt = [ (* from large to small *) 13 | 1000,"M"; 900,"CM"; 500,"D"; 400,"CD"; 100,"C"; 90,"XC"; 14 | 50,"L"; 40,"XL"; 10,"X"; 9,"IX"; 5,"V"; 4,"IV"; 1,"I" 15 | ] in 16 | let buf = Buffer.create 8 in 17 | let a = ref a in 18 | cvt |> List.iter (fun (n, s) -> 19 | while !a >= n do 20 | bprintf buf "%s" s; 21 | a := !a - n 22 | done 23 | ); 24 | Buffer.contents buf 25 | 26 | let rtoa r = 27 | let rtoa = [ 28 | 'I',1; 'V',5; 'X',10; 'L',50; 29 | 'C',100; 'D',500; 'M',1000 30 | ] |> List.to_seq |> CMap.of_seq in 31 | let value = ref 0 in 32 | for i = 0 to String.length r - 1 do 33 | if i < String.length r - 1 && CMap.find r.[i] rtoa < CMap.find r.[i+1] rtoa then (* check next char first *) 34 | value := !value - CMap.find r.[i] rtoa 35 | else 36 | value := !value + CMap.find r.[i] rtoa 37 | done; 38 | !value 39 | 40 | let () = 41 | try 42 | while true do 43 | let str = scanf "%s\n" (fun x -> x) in 44 | try 45 | let a = sscanf str "%d" (fun x -> x) in 46 | printf "%s\n" (ator a) (* Arabic to Roman Numerals *) 47 | with Scan_failure _ -> 48 | printf "%d\n" (rtoa str) (* Roman to Arabic Numerals *) 49 | done 50 | with End_of_file -> () 51 | -------------------------------------------------------------------------------- /cpbook-code/ch1/UVa11616.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | def AtoR(A): 4 | m = {1000: 'M', 900: 'CM', 500: 'D', 400: 'CD', 100: 'C', 90: 'XC',\ 5 | 50: 'L', 40: 'XL', 10: 'X', 9: 'IX', 5: 'V', 4: 'IV', 1: 'I'} 6 | A = int(A) 7 | for value, roman in m.items(): 8 | while A >= value: 9 | print(roman, end='') 10 | A -= value 11 | print() 12 | 13 | def RtoA(R): 14 | m = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000} 15 | value = 0 16 | for i in range(len(R)): 17 | if i+1 < len(R) and m[R[i]] < m[R[i+1]]: 18 | value += m[R[i+1]] - m[R[i]] 19 | elif i-1 >= 0 and m[R[i-1]] < m[R[i]]: 20 | continue 21 | else: 22 | value += m[R[i]] 23 | print(value) 24 | 25 | def main(): 26 | for s in sys.stdin: 27 | s = s.strip('\n') 28 | if s.isdigit(): 29 | AtoR(s) 30 | else: 31 | RtoA(s) 32 | 33 | main() 34 | -------------------------------------------------------------------------------- /cpbook-code/ch1/basic_string.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | 3 | let counter words = 4 | let freq = Hashtbl.create 16 in 5 | words |> List.iter (fun word -> 6 | if not (Hashtbl.mem freq word) then Hashtbl.add freq word 0 7 | else let cnt = Hashtbl.find freq word in Hashtbl.replace freq word (cnt + 1)); 8 | freq 9 | 10 | let count string c = 11 | string |> String.to_seq |> Seq.fold_left (fun acc x -> 12 | if x = c then acc + 1 else acc) 0 13 | 14 | let () = 15 | let oneline = 16 | let rec first_block () = 17 | let line = read_line () in 18 | if line = "......." then [] 19 | else line :: first_block () 20 | in 21 | first_block () 22 | |> String.concat " " 23 | |> Str.global_replace (Str.regexp_string "- ") "" 24 | |> String.lowercase_ascii 25 | in 26 | let last_line = read_line () in 27 | let ndigits, nvowels, nconsonants = 28 | oneline |> String.to_seq |> Seq.fold_left (fun (x, y, z) -> 29 | function 30 | | '0' .. '9' -> (x + 1, y, z) 31 | | 'a' .. 'z' as c -> 32 | if String.contains "aeiou" c then (x, y + 1, z) 33 | else (x, y, z + 1) 34 | | _ -> (x, y, z) 35 | ) (0, 0, 0) 36 | in 37 | let words = oneline |> Str.split (Str.regexp "\\( \\|\\.\\|,\\)+") in 38 | let freq = counter words in 39 | 40 | printf "%s\n" oneline; 41 | printf "%d %d %d\n" ndigits nvowels nconsonants; 42 | printf "%s %s\n" 43 | (List.fold_left min (List.hd words) words) 44 | (List.fold_left max (List.hd words) words); 45 | printf "%d\n" (if Hashtbl.mem freq "cs3233" then 1 else 0); 46 | printf "%d %d %d\n" 47 | (count last_line 's') (count last_line 'h') (count last_line '7') 48 | -------------------------------------------------------------------------------- /cpbook-code/ch1/basic_string.py: -------------------------------------------------------------------------------- 1 | import re 2 | from collections import Counter 3 | 4 | def first_block(): 5 | while True: 6 | line = input() 7 | if line == '.......': 8 | break 9 | yield line 10 | 11 | oneline = ' '.join(first_block()).replace('- ', '').lower() 12 | 13 | digits, alphas, vowels = (sum(pred(c) for c in oneline) 14 | for pred 15 | in (lambda c: c.isdigit(), 16 | lambda c: c.isalpha(), 17 | lambda c: c in 'aeiou')) 18 | consonants = alphas - vowels 19 | 20 | print(oneline) 21 | print(digits, vowels, consonants) 22 | 23 | tokens = list(filter(None, re.split(' |\\.|,', oneline))) 24 | freq = Counter(tokens) 25 | 26 | print(min(tokens), max(tokens)) 27 | print(1 if 'cs3233' in oneline else 0) 28 | 29 | longline = input() 30 | print(longline.count('s'), longline.count('h'), longline.count('7')) 31 | -------------------------------------------------------------------------------- /cpbook-code/ch1/basic_string_out.txt: -------------------------------------------------------------------------------- 1 | i love cs3232 competitive programming and algorithm. of course i love my wife grace suryani very much too. test that there are thirty chars m12345678901234567890123456789 ...... hehehe the line arose only contains six . cannot stop... 2 | 33 58 96 3 | algorithm wife 4 | 0 5 | 569 3 79 6 | -------------------------------------------------------------------------------- /cpbook-code/ch1/factorial.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | import java.math.BigInteger; 3 | class Main { // standard Java class name in UVa OJ 4 | public static void main(String[] args) { 5 | BigInteger fac = BigInteger.ONE; 6 | for (int i = 2; i <= 25; ++i) 7 | fac = fac.multiply(BigInteger.valueOf(i)); // it is in the library! 8 | System.out.println(fac); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /cpbook-code/ch1/factorial.py: -------------------------------------------------------------------------------- 1 | import math 2 | print(math.factorial(25)) 3 | -------------------------------------------------------------------------------- /cpbook-code/ch1/moscowdream.cpp: -------------------------------------------------------------------------------- 1 | #include // a good practice in CP 2 | using namespace std; // same as above 3 | int main() { 4 | int a, b, c, n; scanf("%d %d %d %d", &a, &b, &c, &n); // bug fix below 5 | printf(((a >= 1) && (b >= 1) && (c >= 1) && (a+b+c >= n) && (n >= 3)) ? 6 | "YES\n" : "NO\n"); // use ternary operator 7 | return 0; // for shorter code 8 | } 9 | -------------------------------------------------------------------------------- /cpbook-code/ch1/moscowdream.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | class moscowdream { 3 | public static void main(String[] args) { 4 | Scanner sc = new Scanner(System.in); 5 | int a = sc.nextInt(), b = sc.nextInt(), c = sc.nextInt(), n = sc.nextInt(); 6 | System.out.println(((a >= 1) && (b >= 1) && (c >= 1) && (a+b+c >= n) && (n >= 3)) ? "YES" : "NO"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /cpbook-code/ch1/moscowdream.ml: -------------------------------------------------------------------------------- 1 | open Scanf 2 | open Printf 3 | 4 | let () = 5 | scanf "%d %d %d %d\n" (fun a b c n -> 6 | if (a >= 1) && (b >= 1) && (c >= 1) && (a+b+c >= n) && (n >= 3) then 7 | printf "YES\n" 8 | else 9 | printf "NO\n" 10 | ) 11 | -------------------------------------------------------------------------------- /cpbook-code/ch1/moscowdream.py: -------------------------------------------------------------------------------- 1 | a, b, c, n = map(int, input().split()) 2 | print("YES" if ((a >= 1) and (b >= 1) and (c >= 1) and (a+b+c >= n) and (n >= 3)) else "NO") 3 | -------------------------------------------------------------------------------- /cpbook-code/ch1/scanf.cpp: -------------------------------------------------------------------------------- 1 | #include // include all 2 | using namespace std; 3 | int main() { 4 | int N; scanf("%d\n", &N); 5 | while (N--) { // loop from N,N-1,...,0 6 | char x[110]; // set size a bit larger 7 | scanf("0.%[0-9]...\n", &x); // `&' is optional here 8 | // note: if you are surprised with the technique above, 9 | // please check scanf details in www.cppreference.com 10 | printf("the digits are 0.%s\n", x); 11 | } 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /cpbook-code/ch1/scanf.ml: -------------------------------------------------------------------------------- 1 | open Scanf 2 | open Printf 3 | 4 | let () = 5 | scanf "%d\n" (fun x -> 6 | for i = 1 to x do 7 | scanf "0.%[0-9]...\n" (fun s -> 8 | printf "the digits are 0.%s\n" s 9 | ) 10 | done 11 | ) 12 | -------------------------------------------------------------------------------- /cpbook-code/ch1/scanf_in.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 0.1227... 3 | 0.517611738... 4 | 0.7341231223444344389923899277... 5 | -------------------------------------------------------------------------------- /cpbook-code/ch1/zip.py: -------------------------------------------------------------------------------- 1 | A = [(1, 2, 3), (4, 5, 6)] # list A = 2 tuples of 3 2 | [*zip(*A)] # [(1, 4), (2, 5), (3, 6)] 3 | -------------------------------------------------------------------------------- /cpbook-code/ch2/lineards/UVa10925.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | import java.math.BigInteger; // in package java.math 4 | 5 | class Main { // UVa 10925 - Krakovia 6 | public static void main(String[] args) throws Exception { 7 | BufferedReader br = new BufferedReader( // use BufferedReader 8 | new InputStreamReader(System.in)); 9 | PrintWriter pw = new PrintWriter( // and PrintWriter 10 | new BufferedWriter(new OutputStreamWriter(System.out))); // = fast IO 11 | int caseNo = 0; 12 | while (true) { 13 | StringTokenizer st = new StringTokenizer(br.readLine()); 14 | int N = Integer.parseInt(st.nextToken()); // N bills 15 | int F = Integer.parseInt(st.nextToken()); // F friends 16 | if (N == 0 && F == 0) break; 17 | BigInteger sum = BigInteger.ZERO; // built-in constant 18 | for (int i = 0; i < N; ++i) { // sum the N large bills 19 | BigInteger V = new BigInteger(br.readLine()); // string constructor 20 | sum = sum.add(V); // BigInteger addition 21 | } 22 | pw.printf("Bill #%d costs ", ++caseNo); 23 | pw.printf(sum.toString()); 24 | pw.printf(": each friend should pay "); 25 | pw.printf(sum.divide(BigInteger.valueOf(F)).toString()); 26 | pw.printf("\n\n"); // divide to F friends 27 | } 28 | pw.close(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /cpbook-code/ch2/lineards/UVa10925.py: -------------------------------------------------------------------------------- 1 | import sys 2 | inputs = sys.stdin.read().splitlines() # make Python I/O faster 3 | caseNo = 1 4 | ln = 0 5 | while True: 6 | N, F = map(int, inputs[ln].split()) # N bills, F friends 7 | ln += 1 8 | if N == 0 and F == 0: break 9 | sum = 0 # native support 10 | for _ in range(N): # sum the N large bills 11 | sum += int(inputs[ln]) # native Big Integer 12 | ln += 1 13 | print("Bill #%d costs %d: each friend should pay %d\n" 14 | % (caseNo, sum, sum//F)) # integer division 15 | caseNo += 1 16 | -------------------------------------------------------------------------------- /cpbook-code/ch2/lineards/list.ml: -------------------------------------------------------------------------------- 1 | (* This source code is not as complete as list.cpp *) 2 | 3 | open Printf 4 | 5 | let () = 6 | let s = Stack.create () in 7 | let q = Queue.create () in 8 | 9 | printf "%B\n" (Stack.is_empty s); (* currently s is empty, true *) 10 | printf "==================\n"; 11 | Stack.push 'a' s; 12 | Stack.push 'b' s; 13 | Stack.push 'c' s; 14 | (* stack is LIFO, thus the content of s is currently like this: 15 | * c <- top 16 | * b 17 | * a *) 18 | printf "%c\n" (Stack.top s); (* output 'c' *) 19 | Stack.pop s |> ignore; (* pop topmost *) 20 | printf "%c\n" (Stack.top s); (* output 'b' *) 21 | printf "%B\n" (Stack.is_empty s); (* currently s is not empty, false *) 22 | printf "==================\n"; 23 | 24 | printf "%B\n" (Queue.is_empty q); (* currently q is empty, true *) 25 | printf "==================\n"; 26 | while (not (Stack.is_empty s)) do (* stack s still has 2 more items *) 27 | Queue.push (Stack.pop s) q; (* enqueue 'b', and then 'a' *) 28 | done; 29 | Queue.push 'z' q; (* add one more item *) 30 | printf "%c\n" (Queue.top q); (* prints 'b' *) 31 | 32 | (* output 'b', 'a', then 'z' (until queue is empty), according to the insertion order above *) 33 | printf "==================\n"; 34 | while (not (Queue.is_empty q)) do 35 | printf "%c\n" (Queue.peek q); (* take the front first *) 36 | Queue.pop q |> ignore (* before popping (dequeue-ing) it *) 37 | done; 38 | -------------------------------------------------------------------------------- /cpbook-code/ch2/lineards/resizeable_array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int arr[5] = {7,7,7}; // initial size (5) and initial value {7,7,7,0,0} 6 | vector v(5, 5); // initial size (5) and initial value {5,5,5,5,5} 7 | 8 | printf("arr[2] = %d and v[2] = %d\n", arr[2], v[2]); // 7 and 5 9 | 10 | iota(arr, arr+5, 0); // arr = {0,1,2,3,4} 11 | iota(v.begin(), v.end(), 7); // v = {7,8,9,10,11} 12 | 13 | printf("arr[2] = %d and v[2] = %d\n", arr[2], v[2]); // 2 and 9 14 | 15 | // arr[5] = 5; // undefined behavior 16 | // printf("arr[5] = %d\n", arr[5]); // RTE 17 | // uncomment the line above to see the error (perhaps use -Wall compilation flag) 18 | 19 | v.push_back(77); // vector resizes itself 20 | printf("v[5] = %d\n", v[5]); // 77 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /cpbook-code/ch2/lineards/resizeable_array.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class resizeable_array { 4 | public static void main(String[] args) { 5 | // initial value {7,7,7,0,0} and thus initial size (5) 6 | int[] arr = new int[] {7,7,7,0,0}; 7 | // initial size (5) and initial value {5,5,5,5,5} 8 | ArrayList v = new ArrayList<>(Collections.nCopies(5, 5)); 9 | 10 | // 7 and 5, for Java ArrayList, we must use 'get' 11 | System.out.println("arr[2] = " + arr[2] + " and v[2] = " + v.get(2)); 12 | 13 | for (int i = 0; i < 5; ++i) { 14 | arr[i] = i; // arr = {0,1,2,3,4} 15 | v.set(i, 7+i); // v = {7,8,9,10,11}, but for Java ArrayList, we must use 'set' 16 | } 17 | 18 | // 2 and 9 19 | System.out.println("arr[2] = " + arr[2] + " and v[2] = " + v.get(2)); 20 | 21 | // arr[5] = 5; // static array will generate ArrayIndexOutOfBoundsException 22 | // // uncomment the line above to see the error 23 | 24 | v.add(77); // ArrayList resizes itself (use method add) 25 | System.out.println("v[5] = " + v.get(5)); // 77 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /cpbook-code/ch2/lineards/resizeable_array.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | # Python does not have static array 3 | v = [5] * 5 # Initial size (5) and initial value {5,5,5,5,5} 4 | 5 | print("v[2] = {}".format(v[2])) # 5 6 | 7 | for i in range(5): 8 | v[i] = 7+i; # v = {7,8,9,10,11} 9 | 10 | print("v[2] = {}".format(v[2])) # 9 11 | 12 | # arr[5] = 5; # index out of range error generated as index 5 does not exist 13 | # uncomment the line above to see the error 14 | 15 | v.append(77) # list will resize itself after appending 16 | print("v[5] = {}".format(v[5])) # 77 17 | 18 | main() 19 | -------------------------------------------------------------------------------- /cpbook-code/ch2/nonlineards/pbds.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include // pbds 5 | using namespace __gnu_pbds; 6 | typedef tree, rb_tree_tag, 7 | tree_order_statistics_node_update> ost; 8 | 9 | int main() { 10 | int n = 9; 11 | int A[] = { 2, 4, 7,10,15,23,50,65,71}; // as in Chapter 2 12 | ost tree; 13 | for (int i = 0; i < n; ++i) // O(n log n) 14 | tree.insert(A[i]); 15 | // O(log n) select 16 | cout << *tree.find_by_order(0) << "\n"; // 1-smallest = 2 17 | cout << *tree.find_by_order(n-1) << "\n"; // 9-smallest/largest = 71 18 | cout << *tree.find_by_order(4) << "\n"; // 5-smallest = 15 19 | // O(log n) rank 20 | cout << tree.order_of_key(2) << "\n"; // index 0 (rank 1) 21 | cout << tree.order_of_key(71) << "\n"; // index 8 (rank 9) 22 | cout << tree.order_of_key(15) << "\n"; // index 4 (rank 5) 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /cpbook-code/ch2/nonlineards/priority_queue.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | open Scanf 3 | 4 | module ISMaxPQ = Set.Make (struct 5 | type t = int * string 6 | let compare x y = compare y x 7 | end) 8 | 9 | let () = 10 | (* suppose we enter these 7 money-name pairs below *) 11 | (* 100 john 12 | * 10 billy 13 | * 20 andy 14 | * 100 steven 15 | * 70 felix 16 | * 2000 grace 17 | * 70 martin *) 18 | let pq = ref ISMaxPQ.empty in 19 | pq := ISMaxPQ.add (100, "john") !pq; 20 | pq := ISMaxPQ.add (10, "billy") !pq; 21 | pq := ISMaxPQ.add (20, "andy") !pq; 22 | pq := ISMaxPQ.add (100, "steven") !pq; 23 | pq := ISMaxPQ.add (70, "felix") !pq; 24 | pq := ISMaxPQ.add (2000, "grace") !pq; 25 | pq := ISMaxPQ.add (70, "martin") !pq; 26 | 27 | for _ = 1 to 3 do 28 | let (money, name) as result = ISMaxPQ.min_elt !pq in 29 | pq := ISMaxPQ.remove result !pq; 30 | printf "%s has %d $\n" name money 31 | done; 32 | -------------------------------------------------------------------------------- /cpbook-code/ch2/nonlineards/unordered_map_unordered_set.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | mapper = dict() 3 | used_values = {-1} # initialize with dummy value 4 | 5 | # suppose we enter these 7 name-score pairs below 6 | # john 78 7 | # billy 69 8 | # andy 80 9 | # steven 77 10 | # felix 82 11 | # grace 75 12 | # martin 81 13 | 14 | mapper["john"] = 78 15 | used_values.add(78) 16 | mapper["billy"] = 69 17 | used_values.add(69) 18 | mapper["andy"] = 80 19 | used_values.add(80) 20 | mapper["steven"] = 77 21 | used_values.add(77) 22 | mapper["felix"] = 82 23 | used_values.add(82) 24 | mapper["grace"] = 75 25 | used_values.add(75) 26 | mapper["martin"] = 81 27 | used_values.add(81) 28 | 29 | # then the internal content of mapper/used_values are not really known 30 | # (implementation dependent) 31 | 32 | # iterating through the content of mapper may give any order (input order or jumbled order) 33 | # as the keys are hashed into various slots 34 | for key, value in mapper.items(): 35 | print("{} {}".format(key, value)) 36 | 37 | # map can also be used like this 38 | print("steven's score is {}, grace's score is {}".format(mapper["steven"], mapper["grace"])) 39 | print("==================") 40 | 41 | # there is no lower_bound and upper_bound in a Python set 42 | 43 | # O(1) search, found 44 | print("{}".format(77 in used_values)) 45 | # O(1) search, not found 46 | if not 79 in used_values: 47 | print("79 not found") 48 | 49 | main() 50 | -------------------------------------------------------------------------------- /cpbook-code/ch2/ourown/IntegerPair.java: -------------------------------------------------------------------------------- 1 | class IntegerPair implements Comparable { 2 | Integer _first, _second; 3 | 4 | public IntegerPair(Integer f, Integer s) { 5 | _first = f; 6 | _second = s; 7 | } 8 | 9 | public int compareTo(IntegerPair o) { 10 | if (!this.first().equals(o.first())) 11 | return this.first() - o.first(); 12 | else 13 | return this.second() - o.second(); 14 | } 15 | 16 | Integer first() { return _first; } 17 | Integer second() { return _second; } 18 | } 19 | -------------------------------------------------------------------------------- /cpbook-code/ch2/ourown/IntegerTriple.java: -------------------------------------------------------------------------------- 1 | class IntegerTriple implements Comparable { 2 | Integer _first, _second, _third; 3 | 4 | public IntegerTriple(Integer f, Integer s, Integer t) { 5 | _first = f; 6 | _second = s; 7 | _third = t; 8 | } 9 | 10 | public int compareTo(IntegerTriple o) { 11 | if (!this.first().equals(o.first())) 12 | return this.first() - o.first(); 13 | else if (!this.second().equals(o.second())) 14 | return this.second() - o.second(); 15 | else 16 | return this.third() - o.third(); 17 | } 18 | 19 | Integer first() { return _first; } 20 | Integer second() { return _second; } 21 | Integer third() { return _third; } 22 | 23 | public String toString() { return first() + " " + second() + " " + third(); } 24 | } 25 | -------------------------------------------------------------------------------- /cpbook-code/ch2/ourown/graph_ds.txt: -------------------------------------------------------------------------------- 1 | 6 2 | 0 10 0 0 100 0 3 | 10 0 7 0 8 0 4 | 0 7 0 9 0 0 5 | 0 0 9 0 20 5 6 | 100 8 0 20 0 0 7 | 0 0 0 5 0 0 8 | 6 9 | 2 2 10 5 100 10 | 3 1 10 3 7 5 8 11 | 2 2 7 4 9 12 | 3 3 9 5 20 6 5 13 | 3 1 100 2 8 4 20 14 | 1 4 5 15 | 7 16 | 1 2 10 17 | 1 5 100 18 | 2 3 7 19 | 2 5 8 20 | 3 4 9 21 | 4 5 20 22 | 4 6 5 23 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa00441.cpp: -------------------------------------------------------------------------------- 1 | // Lotto 2 | 3 | #include 4 | using namespace std; 5 | 6 | int main() { 7 | bool first = true; 8 | int k; 9 | while (scanf("%d", &k), k) { 10 | if (!first) printf("\n"); 11 | first = false; 12 | int S[16]; 13 | for (int i = 0; i < k; ++i) scanf("%d", &S[i]); // input: k sorted ints 14 | for (int a = 0 ; a < k-5; ++a) // six nested loops! 15 | for (int b = a+1; b < k-4; ++b) 16 | for (int c = b+1; c < k-3; ++c) 17 | for (int d = c+1; d < k-2; ++d) 18 | for (int e = d+1; e < k-1; ++e) 19 | for (int f = e+1; f < k ; ++f) 20 | printf("%d %d %d %d %d %d\n",S[a],S[b],S[c],S[d],S[e],S[f]); 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa00441.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Main { /* UVa 00441 - Lotto */ 4 | public static void main(String[] args) { 5 | Scanner sc = new Scanner(System.in); 6 | Boolean first = true; 7 | while (true) { 8 | int k = sc.nextInt(); 9 | if (k == 0) break; 10 | if (!first) System.out.println(); 11 | first = false; 12 | int[] S = new int[16]; 13 | for (int i = 0; i < k; ++i) S[i] = sc.nextInt(); // input: k sorted ints 14 | for (int a = 0 ; a < k-5; ++a) // six nested loops! 15 | for (int b = a+1; b < k-4; ++b) 16 | for (int c = b+1; c < k-3; ++c) 17 | for (int d = c+1; d < k-2; ++d) 18 | for (int e = d+1; e < k-1; ++e) 19 | for (int f = e+1; f < k ; ++f) 20 | System.out.printf("%d %d %d %d %d %d\n",S[a],S[b],S[c],S[d],S[e],S[f]); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa00441.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | open Scanf 3 | 4 | let () = 5 | let first = ref true in 6 | try 7 | while true do 8 | let k = scanf "%d " (fun x -> x) in 9 | if k = 0 then raise Exit; 10 | if not !first then printf "\n"; 11 | first := false; 12 | let s = Array.init k (fun _ -> scanf "%d " (fun x -> x)) in 13 | for a = 0 to k-6 do 14 | for b = a+1 to k-5 do 15 | for c = b+1 to k-4 do 16 | for d = c+1 to k-3 do 17 | for e = d+1 to k-2 do 18 | for f = e+1 to k-1 do 19 | printf "%d %d %d %d %d %d\n" s.(a) s.(b) s.(c) s.(d) s.(e) s.(f); 20 | done 21 | done 22 | done 23 | done 24 | done 25 | done 26 | done 27 | with Exit -> 28 | () 29 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa00441.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | first = True 3 | while True: 4 | x = list(map(int, input().split())) 5 | k = x[0] 6 | if k is 0: 7 | break 8 | if first: 9 | first = False 10 | else: 11 | print('') 12 | for a in range(1, k-4): 13 | for b in range(a+1, k-3): 14 | for c in range(b+1, k-2): 15 | for d in range(c+1, k-1): 16 | for e in range(d+1, k): 17 | for f in range(e+1, k+1): 18 | print('{} {} {} {} {} {}'.format(x[a], x[b], x[c], x[d], x[e], x[f])) 19 | 20 | main() 21 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa00725.cpp: -------------------------------------------------------------------------------- 1 | // Division 2 | 3 | #include 4 | using namespace std; 5 | 6 | int main() { 7 | bool first = true; 8 | int N; 9 | while (scanf("%d", &N), N) { 10 | if (!first) printf("\n"); 11 | first = false; 12 | bool noSolution = true; 13 | for (int fghij = 1234; fghij <= 98765/N; ++fghij) { 14 | int abcde = fghij*N; // this way, abcde and fghij are at most 5 digits 15 | int tmp, used = (fghij < 10000); // if digit f=0, then we have to flag it 16 | tmp = abcde; while (tmp) { used |= 1<<(tmp%10); tmp /= 10; } 17 | tmp = fghij; while (tmp) { used |= 1<<(tmp%10); tmp /= 10; } 18 | if (used == (1<<10)-1) { // if all digits are used, print it 19 | printf("%05d / %05d = %d\n", abcde, fghij, N); 20 | noSolution = false; 21 | } 22 | } 23 | if (noSolution) printf("There are no solutions for %d.\n", N); 24 | } 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa00725.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Main { /* UVa 00725 - Division */ 4 | public static void main(String[] args) { 5 | Scanner sc = new Scanner(System.in); 6 | Boolean first = true; 7 | while (true) { 8 | int N = sc.nextInt(); 9 | if (N == 0) break; 10 | if (!first) System.out.println(); 11 | first = false; 12 | Boolean noSolution = true; 13 | for (int fghij = 1234; fghij <= 98765/N; ++fghij) { 14 | int abcde = fghij*N; // this way, abcde and fghij are at most 5 digits 15 | int tmp, used = (fghij < 10000) ? 1 : 0; // if digit f=0, then we have to flag it 16 | tmp = abcde; while (tmp > 0) { used |= 1<<(tmp%10); tmp /= 10; } 17 | tmp = fghij; while (tmp > 0) { used |= 1<<(tmp%10); tmp /= 10; } 18 | if (used == (1<<10)-1) { // if all digits are used, print it 19 | System.out.printf("%05d / %05d = %d\n", abcde, fghij, N); 20 | noSolution = false; 21 | } 22 | } 23 | if (noSolution) System.out.printf("There are no solutions for %d.\n", N); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa00725.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | open Scanf 3 | 4 | let digits n = 5 | let rec aux used n = 6 | match n with 7 | | 0 -> used 8 | | n -> aux (used lor 1 lsl (n mod 10)) (n / 10) 9 | in aux (if n < 10000 then 1 else 0) n 10 | 11 | let () = 12 | let first = ref true in 13 | try 14 | while true do 15 | let n = scanf "%d\n" (fun x -> x) in 16 | if n = 0 then raise Exit; 17 | if not !first then printf "\n"; 18 | first := false; 19 | let no_solution = ref true in 20 | for fghij = 1234 to 98765/n do 21 | let abcde = fghij * n in 22 | let used = digits abcde lor digits fghij in 23 | if used = 1 lsl 10 - 1 then begin 24 | printf "%0.5d / %0.5d = %d\n" abcde fghij n; 25 | no_solution := false; 26 | end 27 | done; 28 | if !no_solution then printf "There are no solutions for %d.\n" n; 29 | done 30 | with Exit -> 31 | () 32 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa00725.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | first = True 3 | while True: 4 | n = int(input()) 5 | if n is 0: 6 | break 7 | if not first: 8 | print('') 9 | first = False 10 | noSolution = True 11 | for fghij in range(1234, (98765//n) + 1): 12 | abcde = fghij * n 13 | used = (fghij < 10000) 14 | tmp = abcde 15 | while tmp is not 0: 16 | used |= 1<<(tmp%10) 17 | tmp //= 10 18 | tmp = fghij 19 | while tmp is not 0: 20 | used |= 1<<(tmp%10) 21 | tmp //= 10 22 | if used == (1<<10) - 1: 23 | print('{:05} / {:05} = {}'.format(abcde, fghij, n)) 24 | noSolution = False 25 | if noSolution: 26 | print('There are no solutions for {}.'.format(n)) 27 | 28 | main() 29 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa00750.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int row[8], a, b, lineCounter; // global variables 5 | 6 | bool canPlace(int r, int c) { 7 | for (int prev = 0; prev < c; ++prev) // check previous Queens 8 | if ((row[prev] == r) || (abs(row[prev]-r) == abs(prev-c))) 9 | return false; // infeasible 10 | return true; 11 | } 12 | 13 | void backtrack(int c) { 14 | if ((c == 8) && (row[b] == a)) { // a candidate sol 15 | printf("%2d %d", ++lineCounter, row[0]+1); 16 | for (int j = 1; j < 8; ++j) printf(" %d", row[j]+1); 17 | printf("\n"); 18 | return; // optional statement 19 | } 20 | for (int r = 0; r < 8; ++r) { // try all possible row 21 | if ((c == b) && (r != a)) continue; // early pruning 22 | if (canPlace(r, c)) // can place a Queen here? 23 | row[c] = r, backtrack(c+1); // put here and recurse 24 | } 25 | } 26 | 27 | int main() { 28 | int TC; scanf("%d", &TC); 29 | while (TC--) { 30 | scanf("%d %d", &a, &b); --a; --b; // to 0-based indexing 31 | memset(row, 0, sizeof row); lineCounter = 0; 32 | printf("SOLN COLUMN\n"); 33 | printf(" # 1 2 3 4 5 6 7 8\n\n"); 34 | backtrack(0); // sub 8! operations 35 | if (TC) printf("\n"); 36 | } 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa00750.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | open Scanf 3 | 4 | let row = Array.make 8 0 5 | let a = ref 0 6 | let b = ref 0 7 | let line_counter = ref 0 8 | 9 | let can_place r c = 10 | List.init c (fun i -> i) |> List.for_all (fun prev -> 11 | row.(prev) <> r && abs (row.(prev) - r) <> abs (prev - c)) 12 | 13 | let rec backtrack c = 14 | if c = 8 then begin 15 | line_counter := !line_counter+1; 16 | printf "%2d %d" !line_counter (row.(0)+1); 17 | for j = 1 to 7 do 18 | printf " %d" (row.(j)+1); 19 | done; 20 | printf "\n" 21 | end 22 | else 23 | for r = 0 to 7 do 24 | if (c = !b) = (r = !a) && can_place r c then begin 25 | row.(c) <- r; backtrack (c+1) 26 | end 27 | done 28 | 29 | let () = 30 | let tc = scanf "%d\n" (fun x -> x) in 31 | for i = 1 to tc do 32 | scanf "\n%d %d\n" (fun x y -> a := x-1; b := y-1); 33 | line_counter := 0; 34 | printf "SOLN COLUMN\n"; 35 | printf " # 1 2 3 4 5 6 7 8\n\n"; 36 | backtrack 0; 37 | if i < tc then printf "\n" 38 | done 39 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa00750.py: -------------------------------------------------------------------------------- 1 | def canPlace(r, c): 2 | for prev in range(c): 3 | if row[prev] == r or abs(row[prev]-r) == abs(prev-c): 4 | return False 5 | return True 6 | 7 | def backtrack(c): 8 | global lineCounter 9 | if c == 8 and row[b] == a: 10 | lineCounter += 1 11 | print("%2d " % lineCounter, *[i+1 for i in row]) 12 | return 13 | for r in range(8): 14 | if c == b and r != a: 15 | continue 16 | if canPlace(r, c): 17 | row[c] = r 18 | backtrack(c+1) 19 | 20 | for tc in range(int(input())): 21 | if tc > 0: 22 | print() 23 | input() 24 | a, b = map(int, input().split()) 25 | a -= 1 26 | b -= 1 27 | row = [0] * 8 28 | lineCounter = 0 29 | print("SOLN COLUMN") 30 | print(" # 1 2 3 4 5 6 7 8\n") 31 | backtrack(0) 32 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa11565.cpp: -------------------------------------------------------------------------------- 1 | // Simple Equations 2 | 3 | #include 4 | using namespace std; 5 | 6 | int main() { 7 | int N; scanf("%d", &N); 8 | while (N--) { 9 | int A, B, C; scanf("%d %d %d", &A, &B, &C); 10 | // 0.150s 11 | // bool sol = false; int x, y, z; 12 | // for (x = -100; x <= 100; ++x) // ~201^3 ~= 8M operations 13 | // for (y = -100; y <= 100; ++y) 14 | // for (z = -100; z <= 100; ++z) 15 | // if ((y != x) && (z != x) && (z != y) && // all 3 must be different 16 | // (x+y+z == A) && (x*y*z == B) && (x*x + y*y + z*z == C)) { 17 | // if (!sol) printf("%d %d %d\n", x, y, z); 18 | // sol = true; 19 | // } 20 | // 0.000s, when x is reduced to -22 to 22 due to x*y*z = B and x <= y <= z so x^3 <= B or x <= B^(1/3) 21 | bool sol = false; int x, y, z; 22 | for (x = -22; (x <= 22) && !sol; ++x) if (x*x <= C) 23 | for (y = -100; (y <= 100) && !sol; ++y) if ((y != x) && (x*x + y*y <= C)) 24 | for (z = -100; (z <= 100) && !sol; ++z) 25 | if ((z != x) && (z != y) && 26 | (x+y+z == A) && (x*y*z == B) && (x*x + y*y + z*z == C)) { 27 | printf("%d %d %d\n", x, y, z); 28 | sol = true; 29 | } 30 | if (!sol) printf("No solution.\n"); 31 | } 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa11565.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Main { /* UVa 11565 - Simple Equations */ 4 | public static void main(String[] args) { 5 | Scanner sc = new Scanner(System.in); 6 | int N = sc.nextInt(); 7 | while (N-- > 0) { 8 | int A = sc.nextInt(), B = sc.nextInt(), C = sc.nextInt(); 9 | Boolean sol = false; 10 | int x, y, z; 11 | for (x = -22; (x <= 22) && !sol; ++x) if (x*x <= C) 12 | for (y = -100; (y <= 100) && !sol; ++y) if ((y != x) && (x*x + y*y <= C)) 13 | for (z = -100; (z <= 100) && !sol; ++z) 14 | if ((z != x) && (z != y) && 15 | (x+y+z == A) && (x*y*z == B) && (x*x + y*y + z*z == C)) { 16 | System.out.printf("%d %d %d\n", x, y, z); 17 | sol = true; 18 | } 19 | if (!sol) System.out.println("No solution."); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa11565.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | open Scanf 3 | 4 | let () = 5 | let n = scanf "%d\n" (fun x -> x) in 6 | for _ = 1 to n do 7 | let a, b, c = scanf "%d %d %d\n" (fun a b c -> a, b, c) in 8 | try 9 | (* for x = -100 to 100 do 10 | * for y = -100 to 100 do 11 | * for z = -100 to 100 do 12 | * if y <> x && z <> x && z <> y (\* all three must be different *\) 13 | * && x + y + z = a 14 | * && x * y * z = b 15 | * && x * x + y * y + z * z = c 16 | * then begin 17 | * printf "%d %d %d\n" x y z; 18 | * raise Exit 19 | * end 20 | * done 21 | * done 22 | * done; *) 23 | for x = -100 to 100 do 24 | for y = -100 to 100 do 25 | if y <> x && x * x + y * y <= c then 26 | for z = -100 to 100 do 27 | if z <> x && z <> y 28 | && x + y + z = a 29 | && x * y * z = b 30 | && x * x + y * y + z * z = c 31 | then begin 32 | printf "%d %d %d\n" x y z; 33 | raise Exit 34 | end 35 | done 36 | done 37 | done; 38 | printf "No solution.\n" 39 | with Exit -> () 40 | done 41 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa11565.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | N = int(input()) 3 | for _ in range(N): 4 | A,B,C = map(int, input().split()) 5 | sol = False 6 | for x in range(-22, 23): 7 | if sol: 8 | break 9 | if x*x <= C: 10 | for y in range(-100, 101): 11 | if sol: 12 | break 13 | if y != x and x*x + y*y <= C: 14 | for z in range(-100, 101): 15 | if sol: 16 | break 17 | if z != x and z != y and x+y+z == A and x*y*z == B and x*x + y*y + z*z == C: 18 | print("{} {} {}".format(x, y, z)) 19 | sol = True 20 | if not sol: 21 | print("No solution.") 22 | 23 | main() 24 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa11742.cpp: -------------------------------------------------------------------------------- 1 | // Social Constraints 2 | 3 | #include 4 | using namespace std; 5 | 6 | const int MAX_n = 8; 7 | const int MAX_m = 20; 8 | 9 | int main() { 10 | int n, m; 11 | while (scanf("%d %d", &n, &m), (n || m)) { 12 | int a[MAX_m], b[MAX_m], c[MAX_m]; 13 | for (int j = 0; j < m; ++j) 14 | scanf("%d %d %d", &a[j], &b[j], &c[j]); 15 | int p[MAX_n]; 16 | for (int i = 0; i < n; ++i) 17 | p[i] = i; 18 | int ans = 0; 19 | do { // try all possible O(n!) permutations, the largest nput 8! = 40320 20 | // check the given social constraints based on 'p' in O(m) 21 | bool all_ok = true; 22 | for (int j = 0; (j < m) && all_ok; ++j) { // check all constraints, max 20, each check 8 = 160 23 | int pos_a = p[a[j]], pos_b = p[b[j]]; 24 | int d_pos = abs(pos_a-pos_b); 25 | if (c[j] > 0) 26 | all_ok = (d_pos <= c[j]); // positive, at most c[j] 27 | else 28 | all_ok = (d_pos >= abs(c[j])); // negative, at least c[j] 29 | } 30 | if (all_ok) ++ans; // all constraints are satisfied by this permutation 31 | } 32 | while (next_permutation(p, p+n)); // the overall time complexity is thus O(m * n!) 33 | printf("%d\n", ans); // overall complexity = 160 * 40320 = 6M, doable 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa11742.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | open Scanf 3 | 4 | let rec permutations = function 5 | | [] -> Seq.return [] 6 | | x::xs -> 7 | let rec interleave ys () = 8 | Seq.Cons (x::ys, match ys with 9 | | [] -> Seq.empty 10 | | y::ys' -> Seq.map (fun p -> y::p) (interleave ys') 11 | ) 12 | in 13 | Seq.flat_map interleave (permutations xs) 14 | 15 | let () = 16 | try 17 | while true do 18 | let n, m = scanf "%d %d\n" (fun x y -> x, y) in 19 | if n = 0 && m = 0 then raise Exit; 20 | let constraints = List.init m (fun _ -> 21 | scanf "%d %d %d\n" (fun a b c -> (a, b, c))) in 22 | let ok (a, b, c) p = 23 | let pos_a = List.nth p a in 24 | let pos_b = List.nth p b in 25 | let d_pos = abs (pos_a-pos_b) in 26 | if c > 0 then d_pos <= c else d_pos >= -c 27 | in 28 | let ans = 29 | Seq.fold_left 30 | (fun a p -> if List.for_all (fun c -> ok c p) constraints then a+1 else a) 31 | 0 32 | (permutations (List.init n (fun i -> i))) 33 | in 34 | printf "%d\n" ans; 35 | done 36 | with Exit -> () 37 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa11742.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import itertools 3 | 4 | def main(): 5 | while True: 6 | n, m = map(int, input().split()) 7 | if n == 0 and m == 0: 8 | break 9 | 10 | constraints = [] 11 | for i in range(m): 12 | a, b, c = map(int, input().split()) 13 | constraints.append((a, b, c)) 14 | 15 | perm = list(itertools.permutations(range(n))) 16 | res = 0 17 | 18 | # try all possible O(n!) permutations, the largest nput 8! = 40320 19 | for arrangement in perm: 20 | all_ok = 1 21 | 22 | # check all constraints, max 20, each check 8 = 160 23 | for constraint in constraints: 24 | i, j, k = constraint 25 | i_pos = -1 26 | j_pos = -1 27 | for ind in range(len(arrangement)): 28 | if arrangement[ind] == i: 29 | i_pos = ind 30 | elif arrangement[ind] == j: 31 | j_pos = ind 32 | 33 | d_pos = abs(i_pos - j_pos) 34 | if (k > 0): all_ok = d_pos <= k 35 | else: all_ok = d_pos >= abs(k) 36 | 37 | if all_ok == 0: break 38 | 39 | # all constraints are satisfied by this permutation 40 | if all_ok == 1: 41 | res += 1 42 | 43 | # the overall time complexity is thus O(m * n!) 44 | # overall complexity = 160 * 40320 = 6M, should be doable with pruning... 45 | print(res) 46 | 47 | main() 48 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa12455.cpp: -------------------------------------------------------------------------------- 1 | // Bars 2 | 3 | #include 4 | using namespace std; 5 | 6 | #define LSOne(S) (S & (-S)) 7 | 8 | const int MAX_n = 20; 9 | 10 | int main() { 11 | int t; scanf("%d", &t); 12 | while (t--) { 13 | int X; scanf("%d", &X); 14 | int n; scanf("%d", &n); 15 | int l[MAX_n]; 16 | for (int i = 0; i < n; ++i) 17 | scanf("%d", &l[i]); 18 | int i; 19 | for (i = 0; i < (1< 0) { 12 | int X = sc.nextInt(); 13 | int n = sc.nextInt(); 14 | int[] l = new int[n]; 15 | for (int i = 0; i < n; ++i) 16 | l[i] = sc.nextInt(); 17 | int i; 18 | for (i = 0; i < (1< 0) { // k is the # of on bits 25 | int two_pow_j = LSOne(mask); // least significant bit 26 | int j = (int)(Math.log(two_pow_j)/Math.log(2)); // 2^j = two_pow_j, get j 27 | sum += l[j]; 28 | mask -= two_pow_j; 29 | } 30 | if (sum == X) break; // the answer is found 31 | } 32 | System.out.println(i < (1< x) in 6 | for _ = 1 to tc do 7 | let target = scanf "%d\n" (fun x -> x) in 8 | let n = scanf "%d\n" (fun x -> x) in 9 | let l = Array.init n (fun i -> scanf "%d " (fun x -> x)) in 10 | try 11 | for mask = 0 to 1 lsl n - 1 do 12 | let sum = 13 | List.init n (fun j -> if mask land 1 lsl j <> 0 then l.(j) else 0) 14 | |> List.fold_left (+) 0 15 | in 16 | if sum = target then raise Exit 17 | done; 18 | printf "NO\n" 19 | with Exit -> 20 | printf "YES\n" 21 | done 22 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/UVa12455.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | def LSOne(S): 4 | return (-S) & S 5 | 6 | def main(): 7 | t = int(input()) 8 | for _ in range(t): 9 | n = int(input()) 10 | p = int(input()) 11 | bars = list(map(int, input().split())) 12 | 13 | found = 0 14 | for i in range(1 << p): #iterate through all subsets 15 | sum = 0 16 | mask = i 17 | while mask > 0: 18 | ls = LSOne(mask) #pick Least Sig Bit 19 | j = (ls ^ (ls-1)).bit_length()-1 #trailing zeroes 20 | sum += bars[j] 21 | mask -= ls 22 | if sum == n: 23 | found = 1 24 | break 25 | 26 | print("YES" if found else "NO") 27 | 28 | main() 29 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/itertools1.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | p = list(itertools.permutations(range(7))) # iterate through p 3 | print(len(p)) # should be 7! = 5040 4 | -------------------------------------------------------------------------------- /cpbook-code/ch3/cs/itertools2.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | N = 7 3 | items = list(range(1, N+1)) 4 | c = [list(itertools.combinations(items, i)) for i in range(1, N+1)] 5 | c = list(itertools.chain(*c)) # combine lists 6 | print(len(c)) # should be 2^7-1 = 127 7 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dnc/IntegerPair.java: -------------------------------------------------------------------------------- 1 | class IntegerPair implements Comparable { 2 | Integer _first, _second; 3 | 4 | public IntegerPair(Integer f, Integer s) { 5 | _first = f; 6 | _second = s; 7 | } 8 | 9 | public int compareTo(IntegerPair o) { 10 | if (!this.first().equals(o.first())) 11 | return this.first() - o.first(); 12 | else 13 | return this.second() - o.second(); 14 | } 15 | 16 | Integer first() { return _first; } 17 | Integer second() { return _second; } 18 | } 19 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dnc/UVa11935.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | events = [] 4 | 5 | def can(f: float): 6 | global events 7 | 8 | cur_d, cur_n, leak_rate, dt = 0, 0, 0, 0 9 | original_f = f 10 | 11 | for i in range(len(events)): 12 | dt = events[i][0] - cur_d 13 | f -= dt / 100 * cur_n 14 | f -= dt * leak_rate 15 | if f < 0: 16 | return False 17 | if events[i][1] <= 0: 18 | cur_n = -events[i][1] 19 | elif events[i][1] == 1: 20 | leak_rate += 1 21 | elif events[i][1] == 2: 22 | f = original_f 23 | elif events[i][1] == 3: 24 | leak_rate = 0 25 | elif events[i][1] == 4: 26 | break 27 | cur_d = events[i][0] 28 | return f >= 0.0 29 | 30 | 31 | if __name__ == '__main__': 32 | for line in sys.stdin: 33 | n = int(line.split()[-1]) 34 | if n == 0: 35 | break 36 | events = [[0, -n]] 37 | 38 | while True: 39 | tkn = sys.stdin.readline().strip('\n').split() 40 | d = int(tkn[0]) 41 | state = ' '.join(tkn[1:]) 42 | if state[0:4] == 'Fuel': 43 | n = int(tkn[-1]) 44 | events.append([d, -n]) 45 | elif state == 'Leak': 46 | events.append([d, 1]) 47 | elif state == 'Gas station': 48 | events.append([d, 2]) 49 | elif state == 'Mechanic': 50 | events.append([d, 3]) 51 | elif state == 'Goal': 52 | events.append([d, 4]) 53 | break 54 | 55 | lo, hi = 0.0, 10000.0 56 | for i in range(50): 57 | mid = (lo+hi)/2 58 | if can(mid): 59 | hi = mid 60 | else: 61 | lo = mid 62 | 63 | print('%.3lf' % hi) 64 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dnc/tricktreat.cpp: -------------------------------------------------------------------------------- 1 | // Trick or Treat 2 | // Ternary Search 3 | 4 | #include 5 | using namespace std; 6 | 7 | const int MAX_n = 50010; 8 | const double INF = 1e9; 9 | 10 | int n; 11 | double xs[MAX_n], ys[MAX_n]; // big, just make it global 12 | 13 | double f(double x) { // square of earliest meeting time if all n kids meet at coordinate (x, y = 0.0) 14 | double ans = -INF; 15 | for (int i = 0; i < n; ++i) // all n kids dash to (x, y = 0.0) 16 | ans = max(ans, (xs[i]-x) * (xs[i]-x) + ys[i] * ys[i]); // avoid computing sqrt which is slow 17 | return ans; 18 | } 19 | 20 | int main() { 21 | ios::sync_with_stdio(false); cin.tie(NULL); 22 | while (cin >> n, n) { 23 | double lo = INF, hi = -INF; 24 | for (int i = 0; i < n; ++i) { 25 | cin >> xs[i] >> ys[i]; 26 | lo = min(lo, xs[i]); 27 | hi = max(hi, xs[i]); 28 | } 29 | for (int i = 0; i < 50; ++i) { // similar as BSTA 30 | double delta = (hi-lo)/3.0; // 1/3rd of the range 31 | double m1 = lo+delta; // 1/3rd away from lo 32 | double m2 = hi-delta; // 1/3rd away from hi 33 | (f(m1) > f(m2)) ? lo = m1 : hi = m2; // f is unimodal 34 | } 35 | cout << fixed << setprecision(10) << lo << " " << sqrt(f(lo)) << "\n"; 36 | } 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dnc/tricktreat.ml: -------------------------------------------------------------------------------- 1 | (* Trick or Treat 2 | * Ternary Search *) 3 | 4 | open Scanf 5 | open Printf 6 | 7 | let solve n = 8 | let xs = Array.make n 0. in 9 | let ys = Array.make n 0. in 10 | let lo = ref max_float in 11 | let hi = ref min_float in 12 | for i = 0 to n - 1 do 13 | scanf "%f %f\n" (fun x y -> xs.(i) <- x; ys.(i) <- y); 14 | lo := min !lo xs.(i); 15 | hi := max !hi xs.(i); 16 | done; 17 | 18 | let f x' = (* square of earliest meeting time if all n kids meet at coordinate (x, y = 0.0) *) 19 | let ans = ref min_float in 20 | Array.iter2 21 | (fun x y -> 22 | ans := max !ans ((x -. x') *. (x -. x') +. y *. y) (* avoid computing sqrt which is slow *) 23 | ) 24 | xs ys; 25 | !ans 26 | in 27 | 28 | for i = 0 to 49 do (* similar as BSTA *) 29 | let delta = (!hi -. !lo) /. 3. in (* 1/3rd of the range *) 30 | let m1 = !lo +. delta in (* 1/3rd away from lo *) 31 | let m2 = !hi -. delta in (* 1/3rd away from hi *) 32 | if f m1 > f m2 then lo := m1 else hi := m2 (* f is unimodal *) 33 | done; 34 | printf "%.10f %.10f\n" !lo (sqrt (f !lo)) 35 | 36 | let () = 37 | let rec loop () = 38 | let n = scanf " %d\n" (fun x -> x) in 39 | if n <> 0 then ( 40 | solve n; 41 | loop () 42 | ) 43 | in 44 | loop () 45 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dnc/tricktreat.py: -------------------------------------------------------------------------------- 1 | import sys, math 2 | 3 | if __name__ == '__main__': 4 | for line in sys.stdin: 5 | n = int(line.strip('\n')) 6 | xs = [0] * n 7 | ys = [0] * n 8 | yq = [0] * n 9 | if n == 0: 10 | break 11 | for i in range(n): 12 | xs[i], ys[i] = map(float, sys.stdin.readline().strip('\n').split()) 13 | yq[i] = ys[i]**2 14 | xs = tuple(xs) 15 | ys = tuple(ys) 16 | yq = tuple(yq) 17 | lo = min(xs) 18 | hi = max(xs) 19 | for i in range(50): 20 | delta = (hi-lo)/3.0 21 | m1 = lo+delta 22 | m2 = hi-delta 23 | 24 | ans_m1 = -1 25 | ans_m2 = -1 26 | for j in range(n): 27 | ans_m1 = max(ans_m1, (xs[j]-m1)**2 + yq[j]) 28 | ans_m2 = max(ans_m2, (xs[j]-m2)**2 + yq[j]) 29 | 30 | if ans_m1 > ans_m2: 31 | lo = m1 32 | else: 33 | hi = m2 34 | 35 | ans = -1 36 | for i in range(n): 37 | ans = max(ans, math.hypot(xs[i]-lo, ys[i])) 38 | 39 | print('%.10lf %.10lf' % (lo, ans)) 40 | 41 | try: 42 | sys.stdin.readline() 43 | except: 44 | pass 45 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/LIS.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class LIS { 4 | static void reconstruct_print(int end, int[] a, int[] p) { 5 | int x = end; 6 | Stack s = new Stack(); 7 | for (; p[x] >= 0; x = p[x]) s.push(a[x]); 8 | System.out.printf("[%d", a[x]); 9 | for (; !s.isEmpty(); s.pop()) System.out.printf(", %d", s.peek()); 10 | System.out.printf("]\n"); 11 | } 12 | 13 | public static void main(String[] args) { 14 | final int MAX_N = 100000; 15 | 16 | int n = 11; 17 | int[] A = new int[] {-7, 10, 9, 2, 3, 8, 8, 1, 2, 3, 4}; 18 | int[] L_id = new int[MAX_N], P = new int[MAX_N]; 19 | Vector L = new Vector(); 20 | 21 | int lis = 0, lis_end = 0; 22 | for (int i = 0; i < n; ++i) { 23 | int pos = Collections.binarySearch(L, A[i]); 24 | if (pos < 0) pos = -(pos + 1); // some adjustments are needed 25 | if (pos >= L.size()) L.add(A[i]); 26 | else L.set(pos, A[i]); 27 | L_id[pos] = i; 28 | P[i] = pos > 0 ? L_id[pos - 1] : -1; 29 | if (pos + 1 > lis) { 30 | lis = pos + 1; 31 | lis_end = i; 32 | } 33 | 34 | System.out.printf("Considering element A[%d] = %d\n", i, A[i]); 35 | System.out.printf("LIS ending at A[%d] is of length %d: ", i, pos + 1); 36 | reconstruct_print(i, A, P); 37 | System.out.println("L is now: " + L); 38 | System.out.printf("\n"); 39 | } 40 | 41 | System.out.printf("Final LIS is of length %d: ", lis); 42 | reconstruct_print(lis_end, A, P); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/LIS.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | 3 | let lower_bound x a n = 4 | let rec aux l r = 5 | if l >= r then l 6 | else 7 | let m = (l+r) / 2 in 8 | if a.(m) >= x then 9 | aux l m 10 | else 11 | aux (m+1) r 12 | in 13 | aux 0 n 14 | 15 | let print_array s a n = 16 | for i = 0 to n-1 do 17 | if i = 0 then printf "%s: [" s 18 | else printf ", "; 19 | printf "%d" a.(i) 20 | done; 21 | printf "]\n" 22 | 23 | let reconstruct_print e a p = 24 | let x = ref e in 25 | let s = Stack.create () in 26 | while p.(!x) >= 0 do 27 | Stack.push a.(!x) s; 28 | x := p.(!x) 29 | done; 30 | printf "[%d" a.(!x); 31 | while not (Stack.is_empty s) do 32 | printf ", %d" (Stack.pop s) 33 | done; 34 | printf "]\n" 35 | 36 | let () = 37 | let a = [|-7; 10; 9; 2; 3; 8; 8; 1; 2; 3; 4|] in 38 | let n = Array.length a in 39 | let l = Array.make n 0 in 40 | let l_id = Array.make n 0 in 41 | let p = Array.make n 0 in 42 | 43 | let lis = ref 0 in 44 | let lis_end = ref 0 in 45 | for i = 0 to n-1 do 46 | let pos = lower_bound a.(i) l !lis in 47 | l.(pos) <- a.(i); 48 | l_id.(pos) <- i; 49 | p.(i) <- if pos > 0 then l_id.(pos-1) else -1; 50 | if pos+1 > !lis then begin 51 | lis := pos+1; 52 | lis_end := i; 53 | end; 54 | 55 | printf "Considering element a.(%d) = %d\n" i a.(i); 56 | printf "LIS ending at a.(%d) is of length %d: " i (pos+1); 57 | reconstruct_print i a p; 58 | print_array "l is now" l !lis; 59 | printf "\n" 60 | done; 61 | 62 | printf "Final LIS is of length %d: " !lis; 63 | reconstruct_print !lis_end a p 64 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/LIS.py: -------------------------------------------------------------------------------- 1 | from bisect import * 2 | 3 | MAX_N = 100000 4 | 5 | def reconstruct_print(end, a, p): 6 | x = end 7 | s = [] 8 | while p[x] >= 0: 9 | s.append(a[x]) 10 | x = p[x] 11 | s.append(a[x]) 12 | print('[' + ', '.join(map(str, s[::-1])) + ']') 13 | 14 | n = 11 15 | A = [-7, 10, 9, 2, 3, 8, 8, 1, 2, 3, 4] 16 | 17 | L = [None] * MAX_N 18 | L_id = [None] * MAX_N 19 | P = [None] * MAX_N 20 | lis = lis_end = 0 21 | for i in range(n): 22 | pos = bisect_left(L, A[i], 0, lis) 23 | L[pos] = A[i] 24 | L_id[pos] = i 25 | P[i] = L_id[pos-1] if pos else -1 26 | if pos+1 > lis: 27 | lis = pos+1 28 | lis_end = i 29 | print('Considering element A[{}] = {}'.format(i, A[i])) 30 | print('LIS ending at A[{}] is of length {}: '.format(i, pos+1), end='') 31 | reconstruct_print(i, A, P) 32 | print('L is now: [' + ', '.join(map(str, L[:lis])) + ']\n') 33 | print('Final LIS is of length {}: '.format(lis), end='') 34 | reconstruct_print(lis_end, A, P) 35 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/Max1DRangeSum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int n = 9, A[] = { 4,-5, 4,-3, 4, 4,-4, 4,-5 };// a sample array A 6 | int sum = 0, ans = 0; 7 | for (int i = 0; i < n; ++i) { // linear scan, O(n) 8 | sum += A[i]; // greedily extend this 9 | ans = max(ans, sum); // keep the cur max RSQ 10 | if (sum < 0) sum = 0; // reset the running sum 11 | } // if it ever dips below 0 12 | // rationale: starting from 0 is better for future 13 | // iterations than starting from -ve running sum 14 | printf("Max 1D Range Sum = %d\n", ans); // should be 9 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/Max1DRangeSum.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Max1DRangeSum { 4 | public static void main(String[] args) { 5 | int n = 9, A[] = { 4, -5, 4, -3, 4, 4, -4, 4, -5 }; // a sample array A 6 | int running_sum = 0, ans = 0; 7 | for (int i = 0; i < n; i++) // O(n) 8 | if (running_sum + A[i] >= 0) { // the overall running sum is still +ve 9 | running_sum += A[i]; 10 | ans = Math.max(ans, running_sum); // keep the largest RSQ overall 11 | } 12 | else // the overall running sum is -ve, we greedily restart here 13 | running_sum = 0; // because starting from 0 is better for future 14 | // iterations than starting from -ve running sum 15 | System.out.printf("Max 1D Range Sum = %d\n", ans); // should be 9 16 | } } 17 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/Max1DRangeSum.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | open Scanf 3 | 4 | let () = 5 | let a = [| 4; -5; 4; -3; 4; 4; -4; 4; -5 |] in (* a sample array a *) 6 | let running_sum = ref 0 in 7 | let ans = ref 0 in 8 | a |> Array.iter (fun x -> (* O(n) *) 9 | if !running_sum + x >= 0 then begin (* the overall running sum is still +ve *) 10 | running_sum := !running_sum + x; 11 | ans := max !ans !running_sum (* keep the largest RSQ overall *) 12 | end 13 | else (* the overall running sum is -ve, we greedily restart here *) 14 | running_sum := 0 (* because starting from 0 is better for future *) 15 | ); (* iterations than starting from -ve running sum *) 16 | printf "Max 1D Range Sum = %d\n" !ans (* should be 9 *) 17 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/Max1DRangeSum.py: -------------------------------------------------------------------------------- 1 | n = 9 2 | A = [4, -5, 4, -3, 4, 4, -4, 4, -5] 3 | running_sum = ans = 0 4 | for i in range(n): 5 | if running_sum + A[i] >= 0: 6 | running_sum += A[i] 7 | ans = max(ans, running_sum) 8 | else: 9 | running_sum = 0 10 | print("Max 1D Range Sum =", ans) 11 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa00108.java: -------------------------------------------------------------------------------- 1 | // Maximum Sum, 0.150s in UVa (C++ version runs in 0.000s) 2 | 3 | import java.util.*; 4 | 5 | class Main { // UVa default class name 6 | public static void main(String[] args) { 7 | Scanner sc = new Scanner(System.in); 8 | int[][] A = new int[110][110]; 9 | int n = sc.nextInt(); 10 | for (int i = 0; i < n; ++i) 11 | for (int j = 0; j < n; ++j) { 12 | A[i][j] = sc.nextInt(); 13 | if (j > 0) A[i][j] += A[i][j-1]; // pre-processing 14 | } 15 | int maxSubRect = -127*100*100; // the lowest possible val 16 | for (int l = 0; l < n; ++l) 17 | for (int r = l; r < n; ++r) { 18 | int subRect = 0; 19 | for (int row = 0; row < n; ++row) { 20 | // Max 1D Range Sum on columns of this row 21 | if (l > 0) subRect += A[row][r] - A[row][l-1]; 22 | else subRect += A[row][r]; 23 | // Kadane's algorithm on rows 24 | if (subRect < 0) subRect = 0; // restart if negative 25 | maxSubRect = Math.max(maxSubRect, subRect); 26 | } 27 | } 28 | System.out.printf("%d\n", maxSubRect); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa00674.cpp: -------------------------------------------------------------------------------- 1 | // Coin Change 2 | 3 | #include 4 | using namespace std; 5 | 6 | int N = 5, V, coinValue[5] = {1, 5, 10, 25, 50}, memo[6][7500]; 7 | // N and coinValue are fixed for this problem, max V is 7489 8 | 9 | int ways(int type, int value) { 10 | if (value == 0) return 1; // one way, use nothing 11 | if ((value < 0) || (type == N)) return 0; // invalid or done 12 | int &ans = memo[type][value]; 13 | if (ans != -1) return ans; // was computed before 14 | return ans = ways(type+1, value) + // ignore this type 15 | ways(type, value-coinValue[type]);// one more of this type 16 | } 17 | 18 | int main() { 19 | memset(memo, -1, sizeof memo); // we only need to initialize this once 20 | while (scanf("%d", &V) != EOF) 21 | printf("%d\n", ways(0, V)); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa00674.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | class UVa00674 { /* Coin Change, 1.492s in Java, 0.038s in C++ */ 5 | // O(NV) DP solution 6 | 7 | // N and coinValue are fixed for this problem, max V is 7489 8 | private static int N = 5, V; 9 | private static int[] coinValue = new int[] {1, 5, 10, 25, 50}; 10 | private static int[][] memo = new int[6][7500]; 11 | 12 | private static int ways(int type, int value) { 13 | if (value == 0) return 1; 14 | if (value < 0 || type == N) return 0; 15 | if (memo[type][value] != -1) return memo[type][value]; 16 | return memo[type][value] = ways(type + 1, value) + ways(type, value - coinValue[type]); 17 | } 18 | 19 | public static void main(String[] args) throws Exception { 20 | // This solution is TLE without using BufferedReader and PrintWriter 21 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 22 | PrintWriter pr = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out))); 23 | 24 | for (int i = 0; i < 6; i++) 25 | for (int j = 0; j < 7500; j++) 26 | memo[i][j] = -1; // we only need to initialize this once 27 | 28 | while (true) { 29 | String line = br.readLine(); 30 | if (line == null) break; 31 | V = Integer.parseInt(line); 32 | pr.printf("%d\n", ways(0, V)); 33 | } 34 | 35 | pr.close(); // do not forget to do this 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa00674.ml: -------------------------------------------------------------------------------- 1 | (* Coin Change *) 2 | 3 | open Printf 4 | open Scanf 5 | 6 | let n = 5 7 | let coin_value = [|1; 5; 10; 25; 50|] 8 | let memo = Array.make_matrix 6 7500 (-1) (* we only need to initialize this once *) 9 | (* n and coin_value are fixed for this problem, max v is 7489 *) 10 | 11 | let rec ways typ value = 12 | if value = 0 then 1 13 | else if value < 0 || typ = n then 0 14 | else if memo.(typ).(value) <> -1 then memo.(typ).(value) 15 | else begin 16 | memo.(typ).(value) <- ways (typ + 1) value + ways typ (value - coin_value.(typ)); 17 | memo.(typ).(value) 18 | end 19 | 20 | let () = 21 | try 22 | while true do 23 | let v = scanf "%d\n" (fun x -> x) in 24 | printf "%d\n" (ways 0 v) 25 | done 26 | with 27 | End_of_file -> () 28 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa00674.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | N = 5 4 | coinValue = [1, 5, 10, 25, 50] 5 | memo = [] 6 | 7 | def ways(coin_type, value): 8 | if value == 0: 9 | return 1 10 | if value < 0 or coin_type == 5: 11 | return 0 12 | if memo[coin_type][value] == -1: 13 | memo[coin_type][value] = ways(coin_type+1, value) + ways(coin_type, value - coinValue[coin_type]) 14 | return memo[coin_type][value] 15 | 16 | def main(): 17 | for i in range(6): 18 | memoTable = [-1] * 40 19 | memo.append(memoTable) 20 | for money in sys.stdin: # read until EOF 21 | money = int(money) 22 | print(ways(0, money)) 23 | 24 | main() 25 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa10003.cpp: -------------------------------------------------------------------------------- 1 | // Cutting Sticks 2 | // Top-Down DP 3 | 4 | #include 5 | using namespace std; 6 | 7 | int l, n, A[55], memo[55][55]; 8 | 9 | int cut(int left, int right) { 10 | if (left+1 == right) return 0; 11 | int &ans = memo[left][right]; 12 | if (ans != -1) return ans; 13 | ans = 2e9; 14 | for (int i = left+1; i < right; ++i) 15 | ans = min(ans, cut(left, i) + cut(i, right) + (A[right]-A[left])); 16 | return ans; 17 | } 18 | 19 | int main() { 20 | while (scanf("%d", &l), l) { 21 | A[0] = 0; 22 | scanf("%d", &n); 23 | for (int i = 1; i <= n; ++i) 24 | scanf("%d", &A[i]); 25 | A[n+1] = l; 26 | memset(memo, -1, sizeof memo); 27 | printf("The minimum cutting is %d.\n", cut(0, n+1)); // start with left = 0 and right = n+1 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa10003.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class UVa10003 { /* Cutting Sticks, 1.762s in Java, 0.302s in C++ */ 4 | // Top-Down DP 5 | 6 | private static int[] arr = new int[55]; 7 | private static int[][] memo = new int[55][55]; 8 | 9 | private static int cut(int left, int right) { 10 | if (left + 1 == right) return 0; 11 | if (memo[left][right] != -1) return memo[left][right]; 12 | 13 | int ans = 2000000000; 14 | for (int i = left + 1; i < right; i++) 15 | ans = Math.min(ans, cut(left, i) + cut(i, right) + (arr[right] - arr[left])); 16 | return memo[left][right] = ans; 17 | } 18 | 19 | public static void main(String[] args) { 20 | Scanner sc = new Scanner(System.in); 21 | int i, j, l, n; 22 | 23 | while (true) { 24 | l = sc.nextInt(); 25 | if (l == 0) 26 | break; 27 | 28 | arr[0] = 0; 29 | n = sc.nextInt(); 30 | for (i = 1; i <= n; i++) 31 | arr[i] = sc.nextInt(); 32 | arr[n + 1] = l; 33 | 34 | for (i = 0; i < 55; i++) 35 | for (j = 0; j < 55; j++) 36 | memo[i][j] = -1; 37 | 38 | // start with left = 0 and right = n + 1 39 | System.out.printf("The minimum cutting is %d.\n", cut(0, n + 1)); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa10003.ml: -------------------------------------------------------------------------------- 1 | (* Cutting Sticks *) 2 | (* Top-Down DP *) 3 | 4 | open Printf 5 | open Scanf 6 | 7 | let a = Array.make 55 0 8 | let memo = Array.make_matrix 55 55 (-1) 9 | 10 | let rec cut left right = 11 | if left + 1 = right then 0 12 | else if memo.(left).(right) <> -1 then memo.(left).(right) 13 | else begin 14 | let ans = ref 2_000_000_000 in 15 | for i = left + 1 to right - 1 do 16 | ans := min !ans (cut left i + cut i right + a.(right) - a.(left)) 17 | done; 18 | memo.(left).(right) <- !ans; 19 | memo.(left).(right) 20 | end 21 | 22 | let () = 23 | try 24 | while true do 25 | let l = scanf "%d\n" (fun x -> x) in 26 | if l = 0 then raise Exit; 27 | let n = scanf "%d\n" (fun x -> x) in 28 | for i = 1 to n do 29 | a.(i) <- scanf "%d " (fun x -> x) 30 | done; 31 | a.(n + 1) <- l; 32 | 33 | Array.iter (fun a -> Array.fill a 0 (Array.length a) (-1)) memo; 34 | printf "The minimum cutting is %d.\n" (cut 0 (n + 1)) (* start with left = 0 and right = n + 1 *) 35 | done 36 | with Exit -> () 37 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa10003.py: -------------------------------------------------------------------------------- 1 | ''' UVa 10003 -- python solution 2 | 3 | O(N^2) 4 | Knuth-Yao optimization is used in this solution 5 | 6 | O(N^3) solution gets TLE in UVa as it is too slow for python despite of N <= 50 7 | It seems there is a lot of cases in the input 8 | ''' 9 | 10 | import sys 11 | 12 | if __name__ == '__main__': 13 | for line in sys.stdin: 14 | l = int(line.strip('\n')) 15 | if l == 0: 16 | break 17 | n = int(sys.stdin.readline().strip('\n')) 18 | A = [0] + list(map(int, sys.stdin.readline().strip('\n').split())) + [l] 19 | 20 | opt = [[0] * (n+3) for _ in range(n+3)] 21 | cut = [[10**9] * (n+2) for _ in range(n+2)] 22 | for i in range(1,n+2): 23 | cut[i-1][i] = 0 24 | opt[i-1][i] = i 25 | for i in range(n+1, -1, -1): 26 | for j in range(i, n+2): 27 | for k in range(opt[i][j-1], opt[i+1][j]+1): # knuth-yao optimization 28 | res = cut[i][k]+cut[k][j]+A[j]-A[i] 29 | if res < cut[i][j]: 30 | cut[i][j] = res 31 | opt[i][j] = k 32 | 33 | print("The minimum cutting is %d." % cut[0][n+1]) 34 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa10003_TLE.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from functools import lru_cache 3 | sys.setrecursionlimit(5000) 4 | 5 | def main(): 6 | inputs = sys.stdin.read().splitlines() # unfortunately still TLE even if I use this 7 | outputs = [] 8 | ln = 0 9 | while True: 10 | l = int(inputs[ln]) 11 | ln += 1 12 | if l == 0: break 13 | n = int(inputs[ln]) 14 | ln += 1 15 | A = list(map(int, inputs[ln].split())) 16 | ln += 1 17 | A.insert(0, 0) 18 | A.insert(len(A), l) 19 | 20 | @lru_cache(maxsize=None) 21 | def cut(left, right): 22 | if left+1 == right: return 0 23 | ans = 2e9 24 | for i in range(left+1, right): 25 | ans = min(ans, cut(left, i) + cut(i, right) + (A[right]-A[left])) 26 | return ans 27 | 28 | outputs.append("The minimum cutting is {}.".format(cut(0, n+1))) # start with left = 0 and right = n+1 29 | 30 | sys.stdout.write('\n'.join(outputs)) 31 | 32 | main() 33 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa10003_knuth_bu.cpp: -------------------------------------------------------------------------------- 1 | /* UVa 10003 2 | 3 | O(N^2) with Knuth-Yao dp optimization 4 | 5 | Bottom-up implementation 6 | */ 7 | #include 8 | using namespace std; 9 | 10 | int l, n; 11 | int A[55]; 12 | int cut[55][55]; 13 | int opt[55][55]; 14 | 15 | int main() { 16 | while (scanf("%d", &l), l) { 17 | A[0] = 0; 18 | scanf("%d", &n); 19 | for (int i = 1; i <= n; ++i) 20 | scanf("%d", &A[i]); 21 | A[n+1] = l; 22 | 23 | for ( int i = 0; i < n+2; ++i ) 24 | for ( int j = 0; j < n+2; ++j ) 25 | cut[i][j] = 1e9; 26 | for ( int i = 1; i < n+3; ++i ) { 27 | cut[i-1][i] = 0; 28 | opt[i-1][i] = i; 29 | } 30 | for ( int i = n+1; i >= 0; --i ) 31 | for ( int j = i; j < n+2; ++j ) 32 | for ( int k = opt[i][j-1]; k <= opt[i+1][j]; ++k ) { 33 | int value = cut[i][k]+cut[k][j]+A[j]-A[i]; 34 | if ( value < cut[i][j] ) { 35 | cut[i][j] = value; 36 | opt[i][j] = k; 37 | } 38 | } 39 | 40 | printf("The minimum cutting is %d.\n", cut[0][n+1]); 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa10003_knuth_td.cpp: -------------------------------------------------------------------------------- 1 | /* UVa 10003 2 | 3 | O(N^2) with Knuth-Yao dp optimization 4 | 5 | Top-down implementation 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | int l, n, A[55], memo[55][55]; 12 | int opt[55][55]; 13 | 14 | int cut(int left, int right) { 15 | if (left+1 >= right) { 16 | opt[left][right] = right; 17 | return 0; 18 | } 19 | int &ans = memo[left][right]; 20 | if (ans != -1) return ans; 21 | ans = 2e9; 22 | cut(left,right-1); 23 | cut(left+1,right); 24 | for (int i = opt[left][right-1]; i <= opt[left+1][right]; ++i) { 25 | int value = cut(left, i) + cut(i, right) + (A[right]-A[left]); 26 | if ( value < ans ) { 27 | ans = value; 28 | opt[left][right] = i; 29 | } 30 | } 31 | return ans; 32 | } 33 | 34 | int main() { 35 | while (scanf("%d", &l), l) { 36 | A[0] = 0; 37 | scanf("%d", &n); 38 | for (int i = 1; i <= n; ++i) 39 | scanf("%d", &A[i]); 40 | A[n+1] = l; 41 | memset(memo, -1, sizeof memo); 42 | memset(opt, -1, sizeof(opt)); 43 | printf("The minimum cutting is %d.\n", cut(0, n+1)); // start with left = 0 and right = n+1 44 | } 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa10130.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class UVa10130 { /* SuperSale */ 4 | // 0-1 Knapsack DP (Top-Down) - faster as not all states are visited 5 | 6 | private static final int MAX_N = 1010; 7 | private static final int MAX_W = 40; 8 | private static int N; 9 | private static int[] V = new int[MAX_N], W = new int[MAX_N]; 10 | private static int[][] memo = new int[MAX_N][MAX_W]; 11 | 12 | private static int dp(int id, int remW) { 13 | if ((id == N) || (remW == 0)) return 0; 14 | if (memo[id][remW] != -1) return memo[id][remW]; 15 | if (W[id] > remW) return memo[id][remW] = dp(id+1, remW); 16 | return memo[id][remW] = Math.max(dp(id+1, remW), 17 | V[id]+dp(id+1, remW-W[id])); 18 | } 19 | 20 | public static void main(String[] args) { 21 | Scanner sc = new Scanner(System.in); 22 | 23 | int T = sc.nextInt(); 24 | while (T-- > 0) { 25 | for (int i = 0; i < MAX_N; ++i) 26 | for (int j = 0; j < MAX_W; ++j) 27 | memo[i][j] = -1; 28 | 29 | N = sc.nextInt(); 30 | for (int i = 0; i < N; ++i) { 31 | V[i] = sc.nextInt(); 32 | W[i] = sc.nextInt(); 33 | } 34 | 35 | int ans = 0; 36 | int G = sc.nextInt(); 37 | while (G-- > 0) { 38 | int MW = sc.nextInt(); 39 | ans += dp(0, MW); 40 | } 41 | 42 | System.out.printf("%d\n", ans); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa10130.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from functools import lru_cache 3 | 4 | sys.setrecursionlimit(100000) 5 | 6 | MAX_N = 1010 7 | MAX_W = 40 8 | 9 | N = 0 10 | V = [0] * MAX_N 11 | W = [0] * MAX_N 12 | 13 | @lru_cache(maxsize=None) 14 | def dp(pid, remW): 15 | if pid == N or remW == 0: 16 | return 0 17 | if W[pid] > remW: 18 | return dp(pid+1, remW) 19 | return max(dp(pid+1, remW), V[pid]+dp(pid+1, remW-W[pid])) 20 | 21 | 22 | if __name__ == '__main__': 23 | T = int(input()) 24 | for _ in range(T): 25 | dp.cache_clear() 26 | N = int(input()) 27 | for i in range(N): 28 | V[i], W[i] = map(int, input().split()) 29 | ans = 0 30 | G = int(input()) 31 | for _ in range(G): 32 | MW = int(input()) 33 | ans += dp(0, MW) 34 | print(ans) 35 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa10943.cpp: -------------------------------------------------------------------------------- 1 | /* How do you add? */ 2 | 3 | // top-down 4 | 5 | /* 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | int N, K, memo[110][110]; 11 | 12 | int ways(int N, int K) { 13 | if (K == 1) // only can use 1 number to add up to N 14 | return 1; // the answer is definitely 1, that number itself 15 | else if (memo[N][K] != -1) 16 | return memo[N][K]; 17 | 18 | // if K > 1, we can choose one number from [0..N] to be one of the number and recursively compute the rest 19 | int total_ways = 0; 20 | for (int split = 0; split <= N; split++) 21 | total_ways = (total_ways + ways(N - split, K - 1)) % 1000000; // we just need the modulo 1M 22 | return memo[N][K] = total_ways; // memoize them 23 | } 24 | 25 | int main() { 26 | memset(memo, -1, sizeof memo); 27 | while (scanf("%d %d", &N, &K), (N || K)) 28 | printf("%d\n", ways(N, K)); // some recursion formula + top down DP 29 | return 0; 30 | } 31 | */ 32 | 33 | 34 | 35 | // bottom-up 36 | 37 | #include 38 | #include 39 | using namespace std; 40 | 41 | int main() { 42 | int i, j, split, dp[110][110], N, K; 43 | 44 | memset(dp, 0, sizeof dp); 45 | 46 | for (i = 0; i <= 100; i++) // these are the base cases 47 | dp[i][1] = 1; 48 | 49 | for (j = 1; j < 100; j++) // these three nested loops form the correct topological order 50 | for (i = 0; i <= 100; i++) 51 | for (split = 0; split <= 100 - i; split++) { 52 | dp[i + split][j + 1] += dp[i][j]; 53 | dp[i + split][j + 1] %= 1000000; 54 | } 55 | 56 | while (scanf("%d %d", &N, &K), (N || K)) 57 | printf("%d\n", dp[N][K]); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa10943.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class UVa10943 { /* How do you add? */ 4 | // top-down 5 | 6 | private static int N, K; 7 | private static int[][] memo = new int[110][110]; 8 | 9 | private static int ways(int N, int K) { 10 | if (K == 1) // only can use 1 number to add up to N 11 | return 1; // the answer is definitely 1, that number itself 12 | else if (memo[N][K] != -1) 13 | return memo[N][K]; 14 | 15 | // if K > 1, we can choose one number from [0..N] to be one of the number 16 | // and recursively compute the rest 17 | int total_ways = 0; 18 | for (int split = 0; split <= N; split++) 19 | total_ways = (total_ways + ways(N - split, K - 1)) % 1000000; // we just need the modulo 1M 20 | return memo[N][K] = total_ways; // memoize them 21 | } 22 | 23 | public static void main(String[] args) { 24 | Scanner sc = new Scanner(System.in); 25 | 26 | for (int i = 0; i < 110; i++) 27 | for (int j = 0; j < 110; j++) 28 | memo[i][j] = -1; 29 | 30 | while (true) { 31 | N = sc.nextInt(); 32 | K = sc.nextInt(); 33 | if (N == 0 && K == 0) 34 | break; 35 | System.out.printf("%d\n", ways(N, K)); // some recursion formula + top down DP 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa10943.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | def main(): 4 | dp = [] 5 | for i in range (110): 6 | dp.append([0] * 110) 7 | 8 | for i in range (101): 9 | dp[i][1] = 1 10 | 11 | for j in range (1, 100): 12 | for i in range (0, 101): 13 | for split in range (0, 101 - i): 14 | dp[i + split][j + 1] += dp[i][j] 15 | dp[i + split][j + 1] %= 1000000 16 | 17 | 18 | inputs = sys.stdin.read().splitlines() 19 | ln = 0 20 | 21 | while True: 22 | N = int(inputs[ln].split(' ')[0].strip()) 23 | K = int(inputs[ln].split(' ')[1].strip()) 24 | if N == 0 and K == 0: 25 | break 26 | ln += 1 27 | print(dp[N][K]) 28 | 29 | main() 30 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa11450_bu.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | open Scanf 3 | 4 | let max_gm = 30 5 | let max_m = 210 6 | 7 | let () = 8 | let tc = scanf "%d\n" (fun x -> x) in 9 | for _ = 1 to tc do 10 | let m, c = scanf "%d %d\n" (fun x y -> x, y) in 11 | let price = Array.init c (fun _ -> 12 | scanf "%d " (fun k -> 13 | Array.init k (fun _ -> scanf "%d " (fun x -> x)))) 14 | in 15 | 16 | let reachable = Array.make_matrix 2 (m+1) false in 17 | price.(0) |> Array.iter (fun p -> 18 | if m-p >= 0 then reachable.(0).(m-p) <- true 19 | ); 20 | 21 | let cur = ref 1 in 22 | for g = 1 to c-1 do 23 | Array.fill reachable.(!cur) 0 (Array.length reachable.(!cur)) false; 24 | for money = 0 to m-1 do 25 | if reachable.(1 - !cur).(money) then 26 | price.(g) |> Array.iter (fun p -> 27 | if money-p >= 0 then 28 | reachable.(!cur).(money-p) <- true 29 | ) 30 | done; 31 | cur := 1 - !cur 32 | done; 33 | 34 | let money = ref 0 in 35 | while !money <= m && not reachable.(1 - !cur).(!money) do 36 | money := !money+1 37 | done; 38 | 39 | if !money = m+1 then printf "no solution\n" 40 | else printf "%d\n" (m - !money) 41 | done 42 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa11450_td.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | open Scanf 3 | 4 | let max_gm = 30 5 | let max_m = 210 6 | 7 | let m = ref 0 8 | let c = ref 0 9 | let memo = Array.make_matrix max_gm max_m (-1) 10 | 11 | let rec shop price g money = 12 | if money < 0 then -1 13 | else if g = !c then !m-money 14 | else if memo.(g).(money) <> -1 then memo.(g).(money) 15 | else 16 | let ans = 17 | price.(g) 18 | |> Array.map (fun p -> shop price (g+1) (money-p)) 19 | |> Array.fold_left max (-1) 20 | in 21 | memo.(g).(money) <- ans; 22 | ans 23 | 24 | let () = 25 | let tc = scanf "%d\n" (fun x -> x) in 26 | for _ = 1 to tc do 27 | scanf "%d %d\n" (fun x y -> m := x; c := y); 28 | let price = Array.init !c (fun _ -> 29 | scanf "%d " (fun k -> 30 | Array.init k (fun _ -> scanf "%d " (fun x -> x)))) 31 | in 32 | let ans = shop price 0 !m in 33 | if ans < 0 then printf "no solution\n" 34 | else printf "%d\n" ans 35 | done 36 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/UVa11450_td.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from functools import lru_cache 3 | sys.setrecursionlimit(5000) 4 | 5 | def main(): # easy to code 6 | TC = int(input()) 7 | for _ in range(TC): 8 | M,C = map(int, input().split()) 9 | price = [[] * 20 for _ in range(C)] 10 | for g in range(C): 11 | price[g] = list(map(int, input().split())) # store k in price[g][0] 12 | 13 | @lru_cache(maxsize=None) # built-in memoization 14 | def dp(g, money): 15 | if money < 0: return -1e9 # fail, return -ve number 16 | if g == C: return M-money # we are done 17 | ans = -1 # start with a -ve number 18 | for k in range(1, price[g][0]+1): # try each model k 19 | ans = max(ans, dp(g+1, money-price[g][k])) 20 | return ans # TOP-DOWN: memoize ans 21 | 22 | if dp(0, M) < 0: # start the top-down DP 23 | print("no solution") 24 | else: 25 | print("{}".format(dp(0, M))) 26 | 27 | main() 28 | -------------------------------------------------------------------------------- /cpbook-code/ch3/dp/beepers_UVa10496.ml: -------------------------------------------------------------------------------- 1 | (* Collecting Beepers *) 2 | 3 | open Printf 4 | open Scanf 5 | 6 | let max_n = 11 7 | 8 | let n = ref 0 9 | let dist = Array.make_matrix max_n max_n 0 10 | let memo = Array.make_matrix max_n (1 lsl (max_n-1)) (-1) (* Karel + max 10 beepers *) 11 | 12 | let rec tsp c mask = (* mask stores the visited coordinates *) 13 | if mask = 1 lsl !n - 1 then dist.(c).(0) (* return trip to close the loop *) 14 | else if memo.(c).(mask) <> -1 then memo.(c).(mask) 15 | else begin 16 | let ans = ref 2_000_000_000 in 17 | for nxt = 1 to !n do (* O(n) here *) 18 | if mask land 1 lsl (nxt-1) = 0 then (* if coordinate nxt is not visited yet *) 19 | ans := min !ans (dist.(c).(nxt) + tsp nxt (mask lor 1 lsl (nxt-1))) 20 | done; 21 | memo.(c).(mask) <- !ans; 22 | memo.(c).(mask) 23 | end 24 | 25 | let () = 26 | let tc = scanf "%d\n" (fun x -> x) in 27 | for _ = 1 to tc do 28 | scanf "%d %d\n" (fun _ _ -> ()); (* these two values are not used *) 29 | let x = Array.make 11 0 in 30 | let y = Array.make 11 0 in 31 | scanf "%d %d\n" (fun a b -> x.(0) <- a; y.(0) <- b); 32 | scanf "%d\n" (fun a -> n := a); 33 | for i = 1 to !n do (* karel's position is at index 0 *) 34 | scanf "%d %d\n" (fun a b -> x.(i) <- a; y.(i) <- b) 35 | done; 36 | for i = 0 to !n do (* build distance table *) 37 | for j = 0 to !n do 38 | dist.(i).(j) <- abs (x.(i)-x.(j)) + abs (y.(i)-y.(j)) (* Manhattan distance *) 39 | done 40 | done; 41 | Array.iter (fun a -> Array.fill a 0 (Array.length a) (-1)) memo; 42 | printf "The shortest path has length %d\n" (tsp 0 0) (* DP-TSP *) 43 | done 44 | -------------------------------------------------------------------------------- /cpbook-code/ch3/greedy/ballotboxes_UVa12390.cpp: -------------------------------------------------------------------------------- 1 | // Distributing Ballot Boxes 2 | 3 | #include 4 | using namespace std; 5 | 6 | typedef tuple dii; // (ratio r, num, den) 7 | 8 | int main() { 9 | int N, B; 10 | while (scanf("%d %d", &N, &B), (N != -1 && B != -1)) { 11 | priority_queue pq; // max pq 12 | for (int i = 0; i < N; ++i) { 13 | int a; scanf("%d", &a); 14 | pq.push({(double)a/1.0, a, 1}); // initially, 1 box/city 15 | } 16 | B -= N; // remaining boxes 17 | while (B--) { // extra box->largest city 18 | auto [r, num, den] = pq.top(); pq.pop(); // current largest city 19 | pq.push({num/(den+1.0), num, den+1}); // reduce its workload 20 | } 21 | printf("%d\n", (int)ceil(get<0>(pq.top()))); // the final answer 22 | } // all other cities in the max pq will have equal or lesser ratio 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /cpbook-code/ch3/greedy/ballotboxes_UVa12390_TLE.py: -------------------------------------------------------------------------------- 1 | import sys, heapq, math 2 | 3 | def main(): 4 | inputs = sys.stdin.read().splitlines() 5 | ln = 0 6 | while True: 7 | N,B = map(int, inputs[ln].split()) 8 | if N == -1 and B == -1: break 9 | ln += 1 10 | 11 | pq = [] # min pq in Python, we will insert negatives to make it max pq 12 | for _ in range(N): 13 | a = int(inputs[ln]) 14 | ln += 1 15 | heapq.heappush(pq, (-a, -a, -1)) # state of tuple = (population_per_box, population, boxes) 16 | ln += 1 # skip this empty line 17 | 18 | B -= N; # every city must be assigned at least one box 19 | while True: 20 | B -= 1 # after that we do a greedy strategy using PQ, to give additional box to the city with currently highest ratio 21 | population_per_box, population, boxes = pq[0] 22 | if -population_per_box == 1.0: break # what's the point to continue, each city already have one box (maybe this optimization is not that useful) 23 | heapq.heappop(pq) # ok pop that 24 | heapq.heappush(pq, (population/(1-boxes), population, boxes-1)) 25 | if B == 0: break # if don't have extra box to reduce overall load 26 | 27 | print(math.ceil(-pq[0][0])) # this is the final answer 28 | 29 | main() 30 | -------------------------------------------------------------------------------- /cpbook-code/ch3/greedy/ballotboxes_UVa12390_bsta.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | def main(): 4 | inputs = sys.stdin.read().splitlines() 5 | ln = 0 6 | while True: 7 | N,B = map(int, inputs[ln].split()) 8 | if N == -1 and B == -1: break 9 | ln += 1 10 | 11 | A = [] 12 | for _ in range(N): 13 | A.append(int(inputs[ln])) 14 | ln += 1 15 | ln += 1 16 | 17 | A = tuple(A) 18 | 19 | L = 1 20 | R = max(A) 21 | ans = R 22 | 23 | # is x a feasible answer? 24 | def can(x): 25 | need = 0 26 | for a in A: 27 | need += (a + x - 1) // x 28 | return need <= B 29 | 30 | # binary search the answer 31 | while L <= R: 32 | m = (L + R) // 2 33 | if can(m): 34 | ans = m 35 | R = m - 1 36 | else: 37 | L = m + 1 38 | 39 | print(ans) 40 | 41 | main() 42 | -------------------------------------------------------------------------------- /cpbook-code/ch3/greedy/grass_UVa10382.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from math import sqrt 3 | 4 | EPS = 1e-9 5 | 6 | class sp: 7 | def __init__(self): 8 | x, y = 0, 0 9 | x_l, x_r = 0.0, 0.0 10 | 11 | 12 | if __name__ == '__main__': 13 | for line in sys.stdin: 14 | n, l, w = map(int, line.strip('\n').split()) 15 | sprinkler = [sp() for _ in range(n)] 16 | for i in range(n): 17 | sprinkler[i].x, sprinkler[i].r = map(int, sys.stdin.readline().strip('\n').split()) 18 | if 2*sprinkler[i].r >= w: 19 | d_x = sqrt(sprinkler[i].r*sprinkler[i].r - (w/2.0)*(w/2.0)) 20 | sprinkler[i].x_l = sprinkler[i].x-d_x 21 | sprinkler[i].x_r = sprinkler[i].x+d_x 22 | else: 23 | sprinkler[i].x_l = sprinkler[i].x_r = sprinkler[i].x 24 | 25 | def cmp(a: sp): 26 | return a.x_l, -a.x_r 27 | sprinkler = sorted(sprinkler, key=cmp) 28 | possible = True 29 | covered = 0.0 30 | ans = 0 31 | skip = 0 32 | for i in range(n): 33 | if not possible: 34 | break 35 | if covered > l: 36 | break 37 | if i < skip: 38 | continue 39 | if sprinkler[i].x_r < covered+EPS: 40 | continue 41 | if sprinkler[i].x_l < covered+EPS: 42 | max_r = -1.0 43 | skip = i 44 | for j in range(i, n): 45 | if not (sprinkler[j].x_l < covered+EPS): 46 | break 47 | if sprinkler[j].x_r > max_r: 48 | max_r = sprinkler[j].x_r 49 | skip = j 50 | ans += 1 51 | covered = max_r 52 | else: 53 | possible = False 54 | 55 | if not possible or covered < l: 56 | print(-1) 57 | else: 58 | print(ans) 59 | -------------------------------------------------------------------------------- /cpbook-code/ch3/greedy/loowater_UVa11292.cpp: -------------------------------------------------------------------------------- 1 | // The Dragon of Loowater 2 | 3 | #include 4 | using namespace std; 5 | 6 | typedef vector vi; 7 | 8 | int main() { 9 | int n, m; 10 | while (scanf("%d %d", &n, &m), (n || m)) { 11 | vi D(n); 12 | vi H(m); 13 | for (int d = 0; d < n; ++d) scanf("%d", &D[d]); 14 | for (int k = 0; k < m; ++k) scanf("%d", &H[k]); 15 | sort(D.begin(), D.end()); // sorting is an important 16 | sort(H.begin(), H.end()); // pre-processing step 17 | int gold = 0, d = 0, k = 0; // both arrays are sorted 18 | while ((d < n) && (k < m)) { // while not done yet 19 | while ((k < m) && (D[d] > H[k])) ++k; // find required knight k 20 | if (k == m) break; // loowater is doomed :S 21 | gold += H[k]; // pay this amount of gold 22 | ++d; ++k; // next dragon & knight 23 | } 24 | if (d == n) printf("%d\n", gold); // all dragons are chopped 25 | else printf("Loowater is doomed!\n"); 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /cpbook-code/ch3/greedy/loowater_UVa11292.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | open Scanf 3 | 4 | let () = 5 | try 6 | while true do 7 | let n, m = scanf "%d %d\n" (fun x y -> x, y) in 8 | if n = 0 && m = 0 then raise Exit; 9 | let dragon = Array.init n (fun _ -> scanf "%d\n" (fun x -> x)) in 10 | Array.sort compare dragon; 11 | let knight = Array.init m (fun _ -> scanf "%d\n" (fun x -> x)) in 12 | Array.sort compare knight; 13 | let gold = ref 0 in 14 | let d = ref 0 in 15 | let k = ref 0 in 16 | begin 17 | try 18 | while !d < n && !k < m do 19 | while !k < m && dragon.(!d) > knight.(!k) do k := !k+1 done; 20 | if !k = m then raise Exit; 21 | gold := !gold + knight.(!d); 22 | d := !d+1; k := !k+1; 23 | done 24 | with Exit -> () 25 | end; 26 | if !d = n then printf "%d\n" !gold 27 | else printf "Loowater is doomed!\n" 28 | done 29 | with Exit -> () 30 | -------------------------------------------------------------------------------- /cpbook-code/ch3/greedy/loowater_UVa11292.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | while True: 3 | n,m = map(int, input().split()) 4 | if n==0 and m==0: 5 | break 6 | D = [9] * n 7 | H = [0] * m 8 | for d in range(n): 9 | D[d] = int(input()) 10 | for k in range(m): 11 | H[k] = int(input()) 12 | D.sort() # sorting is an important 13 | H.sort() # pre-processing step 14 | gold = 0 15 | d = 0 16 | k = 0 # both arrays are sorted 17 | while d < n and k < m: # while not done yet 18 | while k < m and D[d] > H[k]: 19 | k += 1 # find required knight k 20 | if k == m: 21 | break # loowater is doomed :S 22 | gold += H[k] # pay this amount of gold 23 | d += 1 # next dragon 24 | k += 1 # next knight 25 | if d == n: 26 | print("{}".format(gold)) # all dragons are chopped 27 | else: 28 | print("Loowater is doomed!") 29 | 30 | main() 31 | -------------------------------------------------------------------------------- /cpbook-code/ch4/IntegerPair.java: -------------------------------------------------------------------------------- 1 | class IntegerPair implements Comparable { 2 | Integer _first, _second; 3 | 4 | public IntegerPair(Integer f, Integer s) { 5 | _first = f; 6 | _second = s; 7 | } 8 | 9 | public int compareTo(IntegerPair o) { 10 | if (!this.first().equals(o.first())) 11 | return this.first() - o.first(); 12 | else 13 | return this.second() - o.second(); 14 | } 15 | 16 | Integer first() { return _first; } 17 | Integer second() { return _second; } 18 | } 19 | -------------------------------------------------------------------------------- /cpbook-code/ch4/IntegerTriple.java: -------------------------------------------------------------------------------- 1 | class IntegerTriple implements Comparable { 2 | Integer _first, _second, _third; 3 | 4 | public IntegerTriple(Integer f, Integer s, Integer t) { 5 | _first = f; 6 | _second = s; 7 | _third = t; 8 | } 9 | 10 | public int compareTo(IntegerTriple o) { 11 | if (!this.first().equals(o.first())) 12 | return this.first() - o.first(); 13 | else if (!this.second().equals(o.second())) 14 | return this.second() - o.second(); 15 | else 16 | return this.third() - o.third(); 17 | } 18 | 19 | Integer first() { return _first; } 20 | Integer second() { return _second; } 21 | Integer third() { return _third; } 22 | 23 | public String toString() { return first() + " " + second() + " " + third(); } 24 | } 25 | -------------------------------------------------------------------------------- /cpbook-code/ch4/floyd_warshall.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int INF = 1e9; // INF = 1B, not 2^31-1 to avoid overflow 5 | const int MAX_V = 450; // if |V| > 450, you cannot use Floyd Washall's 6 | 7 | int AM[MAX_V][MAX_V]; // it is better to store a big array in the heap 8 | 9 | int main() { 10 | /* 11 | // Graph in Figure 4.30 12 | 5 9 13 | 0 1 2 14 | 0 2 1 15 | 0 4 3 16 | 1 3 4 17 | 2 1 1 18 | 2 4 1 19 | 3 0 1 20 | 3 2 3 21 | 3 4 5 22 | */ 23 | 24 | freopen("floyd_warshall_in.txt", "r", stdin); 25 | 26 | int V, E; scanf("%d %d", &V, &E); 27 | for (int u = 0; u < V; ++u) { 28 | for (int v = 0; v < V; ++v) 29 | AM[u][v] = INF; 30 | AM[u][u] = 0; 31 | } 32 | 33 | for (int i = 0; i < E; ++i) { 34 | int u, v, w; scanf("%d %d %d", &u, &v, &w); 35 | AM[u][v] = w; // directed graph 36 | } 37 | 38 | for (int k = 0; k < V; ++k) // loop order is k->u->v 39 | for (int u = 0; u < V; ++u) 40 | for (int v = 0; v < V; ++v) 41 | AM[u][v] = min(AM[u][v], AM[u][k]+AM[k][v]); 42 | 43 | for (int u = 0; u < V; ++u) 44 | for (int v = 0; v < V; ++v) 45 | printf("APSP(%d, %d) = %d\n", u, v, AM[u][v]); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /cpbook-code/ch4/floyd_warshall.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | public class floyd_warshall { 5 | public static void main(String[] args) throws Exception { 6 | /* 7 | // Graph in Figure 4.20 8 | 5 9 9 | 0 1 2 10 | 0 2 1 11 | 0 4 3 12 | 1 3 4 13 | 2 1 1 14 | 2 4 1 15 | 3 0 1 16 | 3 2 3 17 | 3 4 5 18 | */ 19 | 20 | Scanner sc = new Scanner(new File("floyd_warshall_in.txt")); 21 | int V = sc.nextInt(), E = sc.nextInt(); 22 | 23 | int[][] AM = new int[V][]; 24 | for (int u = 0; u < V; ++u) { 25 | AM[u] = new int[V]; 26 | for (int v = 0; v < V; ++v) 27 | AM[u][v] = 1000000000; // 1e9 to avoid overflow 28 | AM[u][u] = 0; 29 | } 30 | 31 | for (int i = 0; i < E; ++i) { 32 | int u = sc.nextInt(), v = sc.nextInt(), w = sc.nextInt(); 33 | AM[u][v] = w; // directed graph 34 | } 35 | 36 | for (int k = 0; k < V; ++k) // O(v^3) Floyd Warshall's 37 | for (int u = 0; u < V; ++u) 38 | for (int v = 0; v < V; ++v) 39 | AM[u][v] = Math.min(AM[u][v], AM[u][k]+AM[k][v]); 40 | 41 | for (int u = 0; u < V; ++u) 42 | for (int v = 0; v < V; ++v) 43 | System.out.printf("APSP(%d, %d) = %d\n", u, v, AM[u][v]); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /cpbook-code/ch4/floyd_warshall.ml: -------------------------------------------------------------------------------- 1 | let floyd_warshall (n : int) (edges : (int*int*int) list) : int array array = 2 | let dist = Array.make_matrix n n (max_int / 2) in 3 | for u = 0 to n - 1 do 4 | dist.(u).(u) <- 0 5 | done; 6 | edges |> List.iter (fun (u, v, w) -> 7 | dist.(u).(v) <- w (* Directed edge *) 8 | ); 9 | for k = 0 to n - 1 do 10 | for u = 0 to n - 1 do 11 | for v = 0 to n - 1 do 12 | dist.(u).(v) <- min dist.(u).(v) (dist.(u).(k) + dist.(k).(v)) 13 | done 14 | done 15 | done; 16 | dist 17 | 18 | let () = 19 | let (n, m) = Scanf.scanf "%d %d\n" (fun x y -> (x, y)) in 20 | let edges = List.init m (fun _ -> Scanf.scanf "%d %d %d\n" (fun u v w -> (u, v, w))) in 21 | let dist = floyd_warshall n edges in 22 | for u = 0 to n - 1 do 23 | for v = 0 to n - 1 do 24 | Printf.printf "APSP(%d, %d) = %d\n" u v dist.(u).(v) 25 | done 26 | done 27 | -------------------------------------------------------------------------------- /cpbook-code/ch4/floyd_warshall.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | INF = int(1e9) 3 | MAX_V = 450 # if |V| > 450, you cannot use Floyd Washall's 4 | 5 | AM = [[INF for j in range(MAX_V)] for i in range(MAX_V)] 6 | 7 | # Graph in Figure 4.30 8 | # 5 9 9 | # 0 1 2 10 | # 0 2 1 11 | # 0 4 3 12 | # 1 3 4 13 | # 2 1 1 14 | # 2 4 1 15 | # 3 0 1 16 | # 3 2 3 17 | # 3 4 5 18 | 19 | f = open("floyd_warshall_in.txt", "r") 20 | V, E = map(int, f.readline().split(" ")) 21 | for u in range(V): 22 | AM[u][u] = 0 23 | 24 | for i in range(E): 25 | u, v, w = map(int, f.readline().split(" ")) 26 | AM[u][v] = w # directed graph 27 | 28 | for k in range(V): # loop order is k->u->v 29 | for u in range(V): 30 | for v in range(V): 31 | AM[u][v] = min(AM[u][v], AM[u][k] + AM[k][v]) 32 | 33 | for u in range(V): 34 | for v in range(V): 35 | print("APSP({}, {}) = {}".format(u, v, AM[u][v])) 36 | 37 | main() -------------------------------------------------------------------------------- /cpbook-code/ch4/floyd_warshall_in.txt: -------------------------------------------------------------------------------- 1 | 5 9 2 | 0 1 2 3 | 0 2 1 4 | 0 4 3 5 | 1 3 4 6 | 2 1 1 7 | 2 4 1 8 | 3 0 1 9 | 3 2 3 10 | 3 4 5 11 | -------------------------------------------------------------------------------- /cpbook-code/ch4/hierholzer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | typedef vector vi; 5 | 6 | int N; 7 | vector AL; // Directed graph 8 | 9 | vi hierholzer(int s) { 10 | vi ans, idx(N, 0), st; 11 | st.push_back(s); 12 | while (!st.empty()) { 13 | int u = st.back(); 14 | if (idx[u] < (int)AL[u].size()) { // still has neighbor 15 | st.push_back(AL[u][idx[u]]); 16 | ++idx[u]; 17 | } 18 | else { 19 | ans.push_back(u); 20 | st.pop_back(); 21 | } 22 | } 23 | reverse(ans.begin(), ans.end()); 24 | return ans; 25 | } 26 | 27 | int main() { 28 | // The directed graph shown in Figure 4.40 29 | N = 7; 30 | AL.assign(N, {}); 31 | AL[0] = {1, 6}; // A->[B,G] 32 | AL[1] = {2}; // B->C 33 | AL[2] = {3, 4}; // C->[D,E] 34 | AL[3] = {0}; // D->A 35 | AL[4] = {5}; // E->F 36 | AL[5] = {0, 2}; // F->[A,C] 37 | AL[6] = {5}; // G->F 38 | vi ans = hierholzer(0); 39 | for (auto &u : ans) 40 | cout << (char)('A'+u) << " "; 41 | cout << "\n"; 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /cpbook-code/ch4/hierholzer.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.text.*; 3 | 4 | class hierholzer { 5 | private static int N; 6 | private static ArrayList> AL; // Directed graph 7 | 8 | private static ArrayList hierholzer(int s) { 9 | ArrayList ans = new ArrayList<>(); 10 | ArrayList idx = new ArrayList<>(Collections.nCopies(N, 0)); 11 | ArrayList st = new ArrayList<>(); 12 | st.add(s); 13 | while (!st.isEmpty()) { 14 | int u = st.get(st.size()-1); 15 | if (idx.get(u) < AL.get(u).size()) { // still has neighbor 16 | st.add(AL.get(u).get(idx.get(u))); 17 | idx.set(u, idx.get(u)+1); 18 | } 19 | else { 20 | ans.add(u); 21 | st.remove(st.size()-1); 22 | } 23 | } 24 | Collections.reverse(ans); 25 | return ans; 26 | } 27 | 28 | public static void main(String[] args) { 29 | // The directed graph shown in Figure 4.40 30 | N = 7; 31 | AL = new ArrayList<>(N); 32 | for (int i = 0; i < N; ++i) 33 | AL.add(new ArrayList<>()); 34 | AL.get(0).add(1); AL.get(0).add(6); // A->[B,G] 35 | AL.get(1).add(2); // B->C 36 | AL.get(2).add(3); AL.get(2).add(4); // C->[D,E] 37 | AL.get(3).add(0); // D->A 38 | AL.get(4).add(5); // E->F 39 | AL.get(5).add(0); AL.get(5).add(2); // F->[A,C] 40 | AL.get(6).add(5); // G->F 41 | ArrayList ans = hierholzer(0); 42 | for (Integer u : ans) 43 | System.out.print((char)('A'+u) + " "); 44 | System.out.println(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /cpbook-code/ch4/hierholzer.ml: -------------------------------------------------------------------------------- 1 | open Scanf 2 | open Printf 3 | 4 | type graph = int array array (* Adjacency List representation *) 5 | 6 | let hierholzer (adj : graph) (start : int) : int list = 7 | let n = Array.length adj in 8 | let idx = Array.make n 0 in 9 | let rec iter path = function 10 | | [] -> path 11 | | u :: stack' as stack -> 12 | if idx.(u) < Array.length adj.(u) then begin 13 | let v = adj.(u).(idx.(u)) in 14 | idx.(u) <- idx.(u) + 1; 15 | iter path (v :: stack) 16 | end else 17 | iter (u :: path) stack' in 18 | iter [] [start] 19 | 20 | 21 | let () = 22 | let adj = [| 23 | [1; 6]; 24 | [2]; 25 | [3; 4]; 26 | [0]; 27 | [5]; 28 | [0; 2]; 29 | [5]; 30 | |] |> Array.map Array.of_list in 31 | let answer = hierholzer adj 0 in 32 | answer |> List.iter (fun u -> printf "%c " (char_of_int (int_of_char 'A' + u))); 33 | printf "\n" 34 | -------------------------------------------------------------------------------- /cpbook-code/ch4/hierholzer.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | N = 0 4 | AL = [] 5 | 6 | def hierholzer(s): 7 | global AL, N 8 | 9 | ans = [] 10 | idx = [0] * N 11 | st = [s] 12 | 13 | while len(st) != 0: 14 | u = st[-1] 15 | if idx[u] < len(AL[u]): 16 | st.append(AL[u][idx[u]]) 17 | idx[u] += 1 18 | else: 19 | ans.append(u) 20 | st.pop() 21 | 22 | ans = ans[::-1] 23 | return ans 24 | 25 | 26 | def main(): 27 | global AL, N 28 | 29 | N = 7 30 | AL = [list() for _ in range(N)] 31 | AL[0] = [1, 6] 32 | AL[1] = [2] 33 | AL[2] = [3, 4] 34 | AL[3] = [0] 35 | AL[4] = [5] 36 | AL[5] = [0, 2] 37 | AL[6] = [5] 38 | 39 | ans = hierholzer(0) 40 | 41 | for u in ans: 42 | sys.stdout.write(str(chr(ord('A')+u))+' ') 43 | sys.stdout.write('\n') 44 | 45 | 46 | main() 47 | -------------------------------------------------------------------------------- /cpbook-code/ch4/mcbm.ml: -------------------------------------------------------------------------------- 1 | (** [mcbm v_left v_right edges] returns a maximum cardinality bipartite matching. 2 | Left side are numbered [0..v_left-1], right side [0..v_right-1]. 3 | Set both [v_left] and [v_right] to [V] for mixed indices [0..V-1]*) 4 | let mcbm v_left v_right edges = 5 | let adj_l = Array.make v_left [] in 6 | edges |> List.iter (fun (l, r) -> adj_l.(l) <- r :: adj_l.(l)); 7 | let match_r = Array.make v_right (-1) in 8 | let visited_l = Array.make v_left false in 9 | let rec aug l = 10 | if visited_l.(l) then false 11 | else begin 12 | visited_l.(l) <- true; 13 | match adj_l.(l) 14 | |> List.find_opt (fun r -> match_r.(r) = -1 || aug match_r.(r)) with 15 | | Some r -> 16 | match_r.(r) <- l; 17 | true 18 | | None -> false 19 | end 20 | in 21 | (** Greedy pre-processing for trivial Augmenting Paths *) 22 | let free_l = List.init v_left (fun x -> x) |> List.filter (fun l -> 23 | let candidates = adj_l.(l) |> List.filter (fun r -> match_r.(r) = -1) in 24 | if List.length candidates > 0 then 25 | let i = Random.int (List.length candidates) in 26 | match_r.(List.nth candidates i) <- l; 27 | false 28 | else true 29 | ) 30 | in 31 | free_l |> List.iter (fun l-> 32 | let _ = aug l in 33 | Array.fill visited_l 0 v_left false 34 | ); 35 | match_r |> Array.to_list 36 | |> List.mapi (fun r l -> (l, r)) |> List.filter (fun (l, r) -> l <> -1) 37 | 38 | 39 | let () = 40 | mcbm 5 5 [(1, 3); (1, 4); (2, 3)] 41 | |> List.length 42 | |> Printf.printf "Found %d matchings\n" 43 | -------------------------------------------------------------------------------- /cpbook-code/ch4/mcbm.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | match = [] 4 | vis = [] 5 | AL = [] 6 | 7 | def Aug(L): 8 | global match, vis, AL 9 | 10 | if vis[L]: 11 | return 0 12 | vis[L] = 1 13 | for R in AL[L]: 14 | if match[R] == -1 or Aug(match[R]): 15 | match[R] = L 16 | return 1 17 | return 0 18 | 19 | def main(): 20 | global match, vis, AL 21 | 22 | V = 5 23 | Vleft = 3 24 | AL = [list() for _ in range(V)] 25 | AL[1] = [3, 4] 26 | AL[2] = [3] 27 | 28 | freeV = set() 29 | for L in range(Vleft): 30 | freeV.add(L) 31 | match = [-1] * V 32 | MCBM = 0 33 | 34 | for L in range(Vleft): 35 | candidates = [] 36 | for R in AL[L]: 37 | if match[R] == -1: 38 | candidates.append(R) 39 | if len(candidates) > 0: 40 | MCBM += 1 41 | freeV.remove(L) 42 | a = random.randrange(len(candidates)) 43 | match[candidates[a]] = L 44 | 45 | for f in freeV: 46 | vis = [0] * Vleft 47 | MCBM += Aug(f) 48 | 49 | print('Found %d matchings' % MCBM) 50 | 51 | main() 52 | -------------------------------------------------------------------------------- /cpbook-code/ch4/mst/IntegerPair.java: -------------------------------------------------------------------------------- 1 | class IntegerPair implements Comparable { 2 | Integer _first, _second; 3 | 4 | public IntegerPair(Integer f, Integer s) { 5 | _first = f; 6 | _second = s; 7 | } 8 | 9 | public int compareTo(IntegerPair o) { 10 | if (!this.first().equals(o.first())) 11 | return this.first() - o.first(); 12 | else 13 | return this.second() - o.second(); 14 | } 15 | 16 | Integer first() { return _first; } 17 | Integer second() { return _second; } 18 | } 19 | -------------------------------------------------------------------------------- /cpbook-code/ch4/mst/IntegerTriple.java: -------------------------------------------------------------------------------- 1 | class IntegerTriple implements Comparable { 2 | Integer _first, _second, _third; 3 | 4 | public IntegerTriple(Integer f, Integer s, Integer t) { 5 | _first = f; 6 | _second = s; 7 | _third = t; 8 | } 9 | 10 | public int compareTo(IntegerTriple o) { 11 | if (!this.first().equals(o.first())) 12 | return this.first() - o.first(); 13 | else if (!this.second().equals(o.second())) 14 | return this.second() - o.second(); 15 | else 16 | return this.third() - o.third(); 17 | } 18 | 19 | Integer first() { return _first; } 20 | Integer second() { return _second; } 21 | Integer third() { return _third; } 22 | 23 | public String toString() { return first() + " " + second() + " " + third(); } 24 | } 25 | -------------------------------------------------------------------------------- /cpbook-code/ch4/mst/mst_in.txt: -------------------------------------------------------------------------------- 1 | 5 7 2 | 0 1 4 3 | 0 2 4 4 | 0 3 6 5 | 0 4 6 6 | 1 2 2 7 | 2 3 8 8 | 3 4 9 9 | -------------------------------------------------------------------------------- /cpbook-code/ch4/mst/prim.ml: -------------------------------------------------------------------------------- 1 | module PQ = Set.Make (struct 2 | type t = int * int 3 | let compare = compare 4 | end) 5 | 6 | module IntS = Set.Make (struct 7 | type t = int 8 | let compare = compare 9 | end) 10 | 11 | (** [prim n edges] returns the total weight of a MST of the input graph [(0..n-1, edges)] *) 12 | let prim n edges = 13 | let adj = Array.make n [] in 14 | edges |> List.iter (fun (u, v, w) -> 15 | adj.(u) <- (w, v) :: adj.(u); 16 | adj.(v) <- (w, u) :: adj.(v) 17 | ); 18 | let rec loop taken candidates cost = 19 | match PQ.min_elt_opt candidates with 20 | | None -> cost 21 | | Some ((w, u) as e) -> 22 | let candidates = PQ.remove e candidates in 23 | if IntS.mem u taken then loop taken candidates cost 24 | else loop (IntS.add u taken) 25 | (candidates |> PQ.add_seq (List.to_seq adj.(u))) 26 | (cost + w) 27 | in loop (IntS.singleton 0) (PQ.of_list adj.(0)) 0 28 | 29 | open Scanf 30 | open Printf 31 | 32 | let sc = object method nf = bscanf Scanning.stdin end 33 | 34 | let () = 35 | let (n, m) = sc#nf "%d %d\n" (fun x y -> (x, y)) in 36 | let edges = List.init m (fun _ -> sc#nf "%d %d %d\n" (fun u v w -> (u, v, w))) in 37 | prim n edges |> printf "MST cost = %d (Prim's)\n" 38 | -------------------------------------------------------------------------------- /cpbook-code/ch4/sssp/IntegerPair.java: -------------------------------------------------------------------------------- 1 | class IntegerPair implements Comparable { 2 | Integer _first, _second; 3 | 4 | public IntegerPair(Integer f, Integer s) { 5 | _first = f; 6 | _second = s; 7 | } 8 | 9 | public int compareTo(IntegerPair o) { 10 | if (!this.first().equals(o.first())) 11 | return this.first() - o.first(); 12 | else 13 | return this.second() - o.second(); 14 | } 15 | 16 | Integer first() { return _first; } 17 | Integer second() { return _second; } 18 | } 19 | -------------------------------------------------------------------------------- /cpbook-code/ch4/sssp/bellman_ford.ml: -------------------------------------------------------------------------------- 1 | let bellman_ford (n : int) (edges : (int*int*int) list) (source : int) : int array option = 2 | let adj = Array.make n [] in 3 | edges |> List.iter (fun (u, v, w) -> 4 | adj.(u) <- (w, v) :: adj.(u) (* Directed edge *) 5 | ); 6 | let dist = Array.make n max_int in 7 | dist.(source) <- 0; 8 | for _ = 1 to n - 1 do 9 | for u = 0 to n - 1 do 10 | if dist.(u) <> max_int then 11 | adj.(u) |> List.iter (fun (w, v) -> 12 | dist.(v) <- min dist.(v) (dist.(u) + w) 13 | ) 14 | done 15 | done; 16 | let has_neg_cycle = List.init n (fun x -> x) |> List.exists (fun u -> 17 | dist.(u) <> max_int && adj.(u) |> List.exists (fun (w, v) -> 18 | dist.(v) > dist.(u) + w 19 | ) 20 | ) in 21 | if has_neg_cycle then None 22 | else Some dist 23 | 24 | let () = 25 | let (n, m, s) = Scanf.scanf "%d %d %d\n" (fun x y z -> (x, y, z)) in 26 | let edges = List.init m (fun _ -> Scanf.scanf "%d %d %d\n" (fun u v w -> (u, v, w))) in 27 | match bellman_ford n edges s with 28 | | Some dist -> dist |> Array.iteri (fun u d -> 29 | Printf.printf "SSSP(%d, %d) = %d\n" s u d 30 | ) 31 | | None -> Printf.printf "The graph has a negative cycle" 32 | -------------------------------------------------------------------------------- /cpbook-code/ch4/sssp/bellman_ford_in.txt: -------------------------------------------------------------------------------- 1 | 5 5 0 2 | 0 1 1 3 | 0 2 10 4 | 1 3 2 5 | 2 3 -10 6 | 3 4 3 7 | -------------------------------------------------------------------------------- /cpbook-code/ch4/sssp/bellman_ford_moore.ml: -------------------------------------------------------------------------------- 1 | open Scanf 2 | open Printf 3 | 4 | let solve case = 5 | let n, m, s, t = scanf "%d %d %d %d\n" (fun x y z t -> (x, y, z, t)) in 6 | let adj = Array.make n [] in 7 | for i = 1 to m do 8 | let u, v, w = scanf "%d %d %d\n" (fun x y z -> (x, y, z)) in 9 | adj.(u) <- (v, w) :: adj.(u); 10 | adj.(v) <- (u, w) :: adj.(v) 11 | done; 12 | (* SPFA algorithm *) 13 | let dist = Array.make n max_int in 14 | let in_queue = Array.make n false in 15 | let q = Queue.create () in 16 | dist.(s) <- 0; 17 | Queue.add s q; 18 | in_queue.(s) <- true; 19 | while not (Queue.is_empty q) do 20 | let u = Queue.pop q in 21 | in_queue.(u) <- false; 22 | if dist.(u) = max_int then () else 23 | adj.(u) |> List.iter (fun (v, w) -> 24 | if dist.(u) + w < dist.(v) then begin 25 | dist.(v) <- dist.(u) + w; 26 | if not in_queue.(v) then begin 27 | Queue.add v q; 28 | in_queue.(v) <- true 29 | end 30 | end 31 | ) 32 | done; 33 | printf "Case #%d: " case; 34 | if dist.(t) = max_int then printf "unreachable\n" 35 | else printf "%d\n" dist.(t) 36 | 37 | let () = 38 | let tc = scanf "%d\n" (fun x -> x) in 39 | for i = 1 to tc do solve i done 40 | -------------------------------------------------------------------------------- /cpbook-code/ch4/sssp/bellman_ford_moore.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | def main(): 4 | INF = int(1e9) 5 | 6 | f = open("bellman_ford_in.txt", "r") 7 | 8 | V, E, s = map(int, f.readline().split(" ")) 9 | AL = [[] for u in range(V)] 10 | for _ in range(E): 11 | u, v, w = map(int, f.readline().split(" ")) 12 | AL[u].append((v, w)) 13 | 14 | # SPFA from source S 15 | # initially, only source vertex s has dist[s] = 0 and in the queue 16 | dist = [INF for u in range(V)] 17 | dist[s] = 0 18 | q = deque() 19 | q.append(s) 20 | in_queue = [0 for u in range(V)] 21 | in_queue[s] = 1 22 | while (len(q) > 0): 23 | u = q.popleft() # pop from queue 24 | in_queue[u] = 0 25 | for v, w in AL[u]: 26 | if (dist[u]+w >= dist[v]): continue # not improving, skip 27 | dist[v] = dist[u]+w # relax operation 28 | if not in_queue[v]: # add to the queue 29 | q.append(v) # only if v is not 30 | in_queue[v] = 1 # already in the queue 31 | 32 | for u in range(V): 33 | print("SSSP({}, {}) = {}".format(s, u, dist[u])) 34 | 35 | main() 36 | -------------------------------------------------------------------------------- /cpbook-code/ch4/sssp/bfs_in.txt: -------------------------------------------------------------------------------- 1 | 13 16 2 | 0 1 1 2 2 3 0 4 1 5 2 6 3 7 5 6 3 | 4 8 8 9 5 10 6 11 7 12 9 10 10 11 11 12 4 | -------------------------------------------------------------------------------- /cpbook-code/ch4/sssp/dijkstra.ml: -------------------------------------------------------------------------------- 1 | module PQ = Set.Make (struct type t = int * int let compare = compare end) 2 | 3 | module IMap = Map.Make (struct type t = int let compare = compare end) 4 | 5 | let dijkstra (n : int) (edges : (int * int * int) list) (source : int) : int array = 6 | let adj = Array.make n [] in 7 | edges |> List.iter (fun (u, v, w) -> 8 | adj.(u) <- (w, v) :: adj.(u) (* Directed edge *) 9 | ); 10 | let rec loop dist pq = 11 | match PQ.min_elt_opt pq with 12 | | None -> 13 | Array.init n (fun i -> match IMap.find_opt i dist with None -> -1 | Some d -> d) 14 | (* -1 for unreachable vertices *) 15 | | Some ((d, u) as e) -> 16 | let pq = PQ.remove e pq in 17 | if d > IMap.find u dist then loop dist pq 18 | else 19 | let (dist, pq) = adj.(u) |> List.fold_left (fun (dist, pq) (w, v) -> 20 | let dv = d + w in 21 | match IMap.find_opt v dist with 22 | | None -> (IMap.add v dv dist, PQ.add (dv, v) pq) 23 | | Some dv' -> 24 | if dv < dv' then (IMap.add v dv dist, PQ.add (dv, v) pq) 25 | else (dist, pq) 26 | ) (dist, pq) 27 | in 28 | loop dist pq 29 | in 30 | loop (IMap.singleton source 0) (PQ.singleton (0, source)) 31 | 32 | let duplicate edges = edges @ List.map (fun (u, v, w) -> (v, u, w)) edges 33 | 34 | let () = 35 | let (n, m, s) = Scanf.scanf "%d %d %d\n" (fun x y z -> (x, y, z)) in 36 | let edges = List.init m (fun _ -> Scanf.scanf "%d %d %d\n" (fun u v w -> (u, v, w))) in 37 | dijkstra n edges s |> Array.iteri (fun u d -> 38 | Printf.printf "SSSP(%d, %d) = %d\n" s u d 39 | ) 40 | -------------------------------------------------------------------------------- /cpbook-code/ch4/sssp/dijkstra.py: -------------------------------------------------------------------------------- 1 | from heapq import heappush, heappop 2 | 3 | def main(): 4 | INF = int(1e9) 5 | 6 | # Graph in Figure 4.17 7 | # 5 7 0 8 | # 0 1 2 9 | # 0 2 6 10 | # 0 3 7 11 | # 1 3 3 12 | # 1 4 6 13 | # 2 4 1 14 | # 3 4 5 15 | 16 | f = open("dijkstra_in.txt", "r") 17 | 18 | V, E, s = map(int, f.readline().split(" ")) 19 | AL = [[] for u in range(V)] 20 | for _ in range(E): 21 | u, v, w = map(int, f.readline().split(" ")) 22 | AL[u].append((v, w)) # directed graph 23 | 24 | # (Modified) Dijkstra's routine 25 | dist = [INF for u in range(V)] 26 | dist[s] = 0 27 | pq = [] 28 | heappush(pq, (0, s)) 29 | 30 | # sort the pairs by non-decreasing distance from s 31 | while (len(pq) > 0): # main loop 32 | d, u = heappop(pq) # shortest unvisited u 33 | if (d > dist[u]): continue # a very important check 34 | for v, w in AL[u]: # all edges from u 35 | if (dist[u]+w >= dist[v]): continue # not improving, skip 36 | dist[v] = dist[u]+w # relax operation 37 | heappush(pq, (dist[v], v)) 38 | 39 | for u in range(V): 40 | print("SSSP({}, {}) = {}".format(s, u, dist[u])) 41 | 42 | main() 43 | -------------------------------------------------------------------------------- /cpbook-code/ch4/sssp/dijkstra_in.txt: -------------------------------------------------------------------------------- 1 | 5 7 0 2 | 0 1 2 3 | 0 2 6 4 | 0 3 7 5 | 1 3 3 6 | 1 4 6 7 | 2 4 1 8 | 3 4 5 9 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/IntegerPair.java: -------------------------------------------------------------------------------- 1 | class IntegerPair implements Comparable { 2 | Integer _first, _second; 3 | 4 | public IntegerPair(Integer f, Integer s) { 5 | _first = f; 6 | _second = s; 7 | } 8 | 9 | public int compareTo(IntegerPair o) { 10 | if (!this.first().equals(o.first())) 11 | return this.first() - o.first(); 12 | else 13 | return this.second() - o.second(); 14 | } 15 | 16 | Integer first() { return _first; } 17 | Integer second() { return _second; } 18 | } 19 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/UVa00469.ml: -------------------------------------------------------------------------------- 1 | open Scanf 2 | open Printf 3 | 4 | let solve () = 5 | let grid = ref [] in 6 | let line = ref "" in 7 | let _ = read_line () in 8 | let rec read_grid () = 9 | line := read_line (); 10 | if !line.[0] = 'L' || !line.[0] = 'W' then begin 11 | grid := Bytes.of_string !line :: !grid; 12 | read_grid () 13 | end else () in 14 | read_grid (); 15 | 16 | let grid = !grid |> List.rev |> Array.of_list in 17 | let n, m = Array.length grid, Bytes.length grid.(0) in 18 | let rec flood_fill r c x y = 19 | if r < 0 || r >= n || c < 0 || c >= m then 0 else 20 | if Bytes.get grid.(r) c <> x then 0 else begin 21 | Bytes.set grid.(r) c y; 22 | [(1, 0); (1, 1); (0, 1); (-1, 1); (-1, 0); (-1, -1); (0, -1); (1, -1)] 23 | |> List.fold_left (fun sum (dr, dc) -> 24 | sum + flood_fill (r + dr) (c + dc) x y 25 | ) 1 26 | end 27 | in 28 | 29 | let rec query () = 30 | let r, c = sscanf !line "%d %d" (fun x y -> (x - 1, y - 1)) in 31 | printf "%d\n" (flood_fill r c 'W' '.'); 32 | let _ = flood_fill r c '.' 'W' in 33 | try 34 | line := read_line (); 35 | if !line = "" then () 36 | else query () 37 | with _ -> () 38 | in 39 | query () 40 | 41 | let () = 42 | let tc = read_int () in 43 | for _ = 1 to tc do solve () done 44 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/UVa00469.py: -------------------------------------------------------------------------------- 1 | ''' 2 | the algorithm is similar to CPP, 3 | but the output is stored in table 4 | to avoid repeated call of floodfill 5 | ''' 6 | 7 | import sys, copy 8 | 9 | sys.setrecursionlimit(100000) 10 | 11 | line = ['.'] * 150 12 | grid = ['.' * 150] * 150 13 | R = 0 14 | C = 0 15 | 16 | dr = (1, 1, 0,-1,-1,-1, 0, 1) 17 | dc = (0, 1, 1, 1, 0,-1,-1,-1) 18 | 19 | visited = [] 20 | 21 | def floodfill(r, c, c1, c2): 22 | global grid, visited 23 | 24 | ans = 1 25 | grid[r][c] = c2 26 | visited.append((r, c)) 27 | for d in range(8): 28 | if 0 <= r+dr[d] < R and 0 <= c+dc[d] < C and grid[r+dr[d]][c+dc[d]] == c1: 29 | ans += floodfill(r+dr[d], c+dc[d], c1, c2) 30 | return ans 31 | 32 | if __name__ == '__main__': 33 | TC = int(input()) 34 | input() 35 | 36 | for tc in range(TC): 37 | R = 0 38 | while True: 39 | grid[R] = list(input()) 40 | if grid[R][0] != 'L' and grid[R][0] != 'W': 41 | break 42 | R += 1 43 | C = len(grid[0]) 44 | 45 | output = {} 46 | 47 | line = ''.join(grid[R]) 48 | while True: 49 | row, col = map(int, line.split()) 50 | row -= 1 51 | col -= 1 52 | 53 | if (row, col) not in output: 54 | visited = [] 55 | ans = floodfill(row, col, 'W', '.') 56 | for cell in visited: 57 | output[cell] = ans 58 | 59 | print(output[(row, col)]) 60 | 61 | try: 62 | line = input() 63 | if line == '': 64 | break 65 | except: 66 | break 67 | 68 | if tc < TC-1: 69 | print() 70 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/UVa10004.cpp: -------------------------------------------------------------------------------- 1 | // Bicoloring 2 | 3 | #include 4 | using namespace std; 5 | 6 | typedef vector vi; 7 | 8 | const int INF = 1e9; 9 | 10 | int main() { 11 | int n; 12 | while (scanf("%d", &n), n) { 13 | vector AL(n, vi()); // notice: vi, not vii 14 | int l; scanf("%d", &l); 15 | while (l--) { 16 | int a, b; scanf("%d %d", &a, &b); 17 | AL[a].push_back(b); 18 | AL[b].push_back(a); // bidirectional 19 | } 20 | int s = 0; 21 | queue q; q.push(s); 22 | vi color(n, INF); color[s] = 0; 23 | bool isBipartite = true; // add a Boolean flag 24 | while (!q.empty() && isBipartite) { // as with original BFS 25 | int u = q.front(); q.pop(); 26 | for (auto &v : AL[u]) { 27 | if (color[v] == INF) { // don't record distances 28 | color[v] = 1-color[u]; // just record two colors 29 | q.push(v); 30 | } 31 | else if (color[v] == color[u]) { // u & v have same color 32 | isBipartite = false; // a coloring conflict :( 33 | break; // optional speedup 34 | } 35 | } 36 | } 37 | printf("%sBICOLORABLE.\n", (isBipartite ? "" : "NOT ")); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/UVa10004.java: -------------------------------------------------------------------------------- 1 | // Bicoloring 2 | 3 | import java.util.*; 4 | 5 | class Main { 6 | private static final int INF = 1000000000; 7 | 8 | public static void main(String[] args) { 9 | Scanner sc = new Scanner(System.in); 10 | while (true) { 11 | int n = sc.nextInt(); 12 | if (n == 0) break; 13 | ArrayList> AL = new ArrayList<>(); 14 | for (int i = 0; i < n; ++i) 15 | AL.add(new ArrayList<>()); 16 | int l = sc.nextInt(); 17 | while (l-- > 0) { 18 | int a = sc.nextInt(), b = sc.nextInt(); 19 | AL.get(a).add(b); 20 | AL.get(b).add(a); // bidirectional 21 | } 22 | int s = 0; 23 | Queue q = new LinkedList<>(); q.add(s); 24 | ArrayList color = new ArrayList<>(Collections.nCopies(n, INF)); color.set(s, 0); 25 | Boolean isBipartite = true; // add a Boolean flag 26 | while (!q.isEmpty() && isBipartite) { // as with original BFS 27 | int u = q.poll(); 28 | for (Integer v : AL.get(u)) { 29 | if (color.get(v) == INF) { // don't record distances 30 | color.set(v, 1-color.get(u)); // just record two colors 31 | q.add(v); 32 | } 33 | else if (color.get(v) == color.get(u)) { // u & v have same color 34 | isBipartite = false; // a coloring conflict :( 35 | break; // optional speedup 36 | } 37 | } 38 | } 39 | System.out.printf("%sBICOLORABLE.\n", (isBipartite ? "" : "NOT ")); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/UVa10004.ml: -------------------------------------------------------------------------------- 1 | open Scanf 2 | open Printf 3 | 4 | let solve n m = 5 | let adj = Array.make n [] in 6 | for i = 1 to m do 7 | let u, v = scanf "%d %d\n" (fun x y -> (x, y)) in 8 | adj.(u) <- v :: adj.(u); 9 | adj.(v) <- u :: adj.(v) 10 | done; 11 | let color = Array.make n (-1) in 12 | let q = Queue.create () in 13 | Queue.add 0 q; 14 | let is_bipartite = ref true in 15 | while not (Queue.is_empty q) && !is_bipartite do 16 | let u = Queue.pop q in 17 | adj.(u) |> List.iter (fun v -> 18 | if color.(v) = -1 then begin 19 | color.(v) <- 1 - color.(u); 20 | Queue.add v q 21 | end else if color.(u) = color.(v) then 22 | is_bipartite := false 23 | ) 24 | done; 25 | printf "%sBICOLORABLE.\n" (if !is_bipartite then "" else "NOT ") 26 | 27 | let () = 28 | let rec loop () = 29 | try 30 | let n, m = scanf "%d\n%d\n" (fun x y -> (x, y)) in 31 | solve n m; 32 | loop () 33 | with _ -> () in 34 | loop () 35 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/UVa10004.py: -------------------------------------------------------------------------------- 1 | # Bicoloring 2 | 3 | from collections import deque 4 | 5 | def main(): 6 | INF = int(1e9) 7 | while (True): 8 | n = int(input()) 9 | if (n == 0): 10 | break 11 | AL = [[] for i in range(n)] 12 | 13 | l = int(input()) 14 | for i in range(l): 15 | a, b = map(int, input().split(" ")) 16 | AL[a].append(b) 17 | AL[b].append(a) # bidirectional 18 | 19 | s = 0 20 | q = deque() 21 | q.append(s) 22 | color = [INF for i in range(n)] 23 | color[s] = 0 24 | isBipartite = True # add one more boolean flag, initially true 25 | while (len(q) > 0 and isBipartite): 26 | u = q.popleft() 27 | for v in AL[u]: 28 | if (color[v] == INF): # but, instead of recording distance, 29 | color[v] = 1 - color[u] # we just record two colors {0, 1} 30 | q.append(v) 31 | elif (color[v] == color[u]): # u & v have the same color 32 | isBipartite = False # we have a coloring conflict 33 | break 34 | 35 | print("{}BICOLORABLE.".format("" if isBipartite else "NOT ")) 36 | 37 | main() -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/UVa11060.py: -------------------------------------------------------------------------------- 1 | from heapq import heappush, heappop 2 | import sys 3 | 4 | # Beverages 5 | 6 | def main(): 7 | caseNo = 1 8 | while (True): 9 | AL = [] 10 | mapper = {} 11 | reverseMapper = {} 12 | try: 13 | N = int(input()) 14 | except: 15 | break 16 | for i in range(0, N): 17 | B1 = input() 18 | mapper[B1] = i 19 | reverseMapper[i] = B1 20 | AL.append([]) 21 | 22 | in_degree = [0 for i in range(110)] 23 | M = int(input()) 24 | for i in range(M): 25 | B1, B2 = input().split(" ") 26 | a = mapper[B1] 27 | b = mapper[B2] 28 | AL[a].append(b) 29 | in_degree[b] += 1 30 | 31 | sys.stdout.write("Case #{}: Dilbert should drink beverages in this order:".format(caseNo)) 32 | caseNo += 1 33 | 34 | # enqueue vertices with zero incoming degree into a (priority) queue pq 35 | pq = [] # min priority queue 36 | for u in range(N): 37 | if in_degree[u] == 0: # all vertices with 0 in-degree can be processed 38 | heappush(pq, u) # smaller index goes first 39 | 40 | while (len(pq) > 0): # Kahn's algorithm 41 | u = heappop(pq) 42 | sys.stdout.write(" "+reverseMapper[u]) 43 | for v in AL[u]: # process u 44 | in_degree[v] -= 1 # virtually 'remove' u->v 45 | if in_degree[v] == 0: # v is the next candidate 46 | heappush(pq, v) # smallest id to front 47 | 48 | print(".\n"); 49 | try: 50 | input() 51 | except: 52 | break 53 | main() -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/articulation_in.txt: -------------------------------------------------------------------------------- 1 | 6 2 | 1 1 0 3 | 5 0 0 2 0 3 0 4 0 5 0 4 | 1 1 0 5 | 1 1 0 6 | 2 1 0 5 0 7 | 2 1 0 4 0 8 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/cyclecheck.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from enum import Enum 3 | 4 | class flag(Enum): 5 | UNVISITED = -1 6 | EXPLORED = -2 7 | VISITED = -3 8 | 9 | AL = [] 10 | dfs_num = [] 11 | dfs_parent = [] 12 | 13 | def cycleCheck(u): 14 | global AL 15 | global dfs_num 16 | global dfs_parent 17 | 18 | dfs_num[u] = flag.EXPLORED.value 19 | for v, w in AL[u]: 20 | if dfs_num[v] == flag.UNVISITED.value: 21 | dfs_parent[v] = u 22 | cycleCheck(v) 23 | elif dfs_num[v] == flag.EXPLORED.value: 24 | if v == dfs_parent[u]: 25 | printf(' Bidirectional Edge (%d, %d)-(%d, %d)' % (u, v, v, u)) 26 | else: 27 | print('Back Edge (%d, %d) (Cycle)' % (u, v)) 28 | dfs_num[u] = flag.VISITED.value 29 | 30 | 31 | def main(): 32 | global AL 33 | global dfs_num 34 | global dfs_parent 35 | 36 | fp = open('scc_in.txt', 'r') 37 | 38 | V = int(fp.readline().strip()) 39 | AL = [[] for _ in range(V)] 40 | for u in range(V): 41 | tkn = list(map(int, fp.readline().strip().split())) 42 | k = tkn[0] 43 | for i in range(k): 44 | v, w = [tkn[2*i+1], tkn[2*i+2]] 45 | AL[u].append((v, w)) 46 | 47 | print('Graph Edges Property Check') 48 | dfs_num = [flag.UNVISITED.value] * V 49 | dfs_parent = [-1] * V 50 | for u in range(V): 51 | if dfs_num[u] == flag.UNVISITED.value: 52 | cycleCheck(u) 53 | 54 | 55 | main() 56 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/dfs_cc.ml: -------------------------------------------------------------------------------- 1 | open Scanf 2 | open Printf 3 | 4 | type graph = int list array (* Adjacency List representation *) 5 | 6 | let range n = List.init n (fun x -> x) 7 | 8 | (** Returns a list of DFS orderings of all connected components *) 9 | let dfs (adj : graph) : int list list = 10 | let n = Array.length adj in 11 | let visited = Array.make n false in 12 | let rec visit order u = 13 | visited.(u) <- true; 14 | adj.(u) |> List.fold_left (fun order v -> 15 | if visited.(v) then order 16 | else visit order v 17 | ) (u :: order) 18 | in 19 | range n |> List.fold_left (fun components u -> 20 | if visited.(u) then components 21 | else (visit [] u |> List.rev) :: components 22 | ) [] |> List.rev 23 | 24 | 25 | let () = 26 | let ic = Scanning.open_in "dfs_cc_in.txt" in 27 | let sc = object method nf = bscanf ic end in 28 | let n = sc#nf " %d " (fun x -> x) in 29 | let adj = Array.init n (fun _ -> 30 | sc#nf " %d " (fun degree -> 31 | List.init degree (fun _ -> sc#nf " %d %d " (fun v w -> v))) (* Ignoring weight *) 32 | ) in 33 | 34 | printf "Standard DFS Demo (the input graph must be UNDIRECTED)\n"; 35 | let ccs = dfs adj in 36 | ccs |> List.iteri (fun i component -> 37 | printf "CC %d:" (i + 1); 38 | component |> List.iter (printf " %d"); 39 | printf "\n" 40 | ); 41 | ccs |> List.length |> printf "There are %d connected components\n"; 42 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/dfs_cc.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from enum import Enum 3 | 4 | class flag(Enum): 5 | UNVISITED = -1 6 | VISITED = -2 7 | 8 | AL = [] 9 | dfs_num = [] 10 | 11 | def dfs(u): 12 | global AL 13 | global dfs_num 14 | 15 | sys.stdout.write(' '+str(u)) 16 | dfs_num[u] = flag.VISITED.value 17 | for v, w in AL[u]: 18 | if dfs_num[v] == flag.UNVISITED.value: 19 | dfs(v) 20 | 21 | 22 | def main(): 23 | global AL 24 | global dfs_num 25 | 26 | fp = open('dfs_cc_in.txt', 'r') 27 | 28 | V = int(fp.readline().strip()) 29 | AL = [[] for _ in range(V)] 30 | for u in range(V): 31 | tkn = list(map(int, fp.readline().strip().split())) 32 | k = tkn[0] 33 | for i in range(k): 34 | v, w = tkn[2*i+1], tkn[2*i+2] 35 | AL[u].append((v, w)) 36 | 37 | print('Standard DFS Demo (the input graph must be UNDIRECTED)') 38 | dfs_num = [flag.UNVISITED.value] * V 39 | numCC = 0 40 | for u in range(V): 41 | if dfs_num[u] == flag.UNVISITED.value: 42 | numCC += 1 43 | sys.stdout.write('CC %d:' % numCC) 44 | dfs(u) 45 | sys.stdout.write('\n') 46 | print('There are %d connected components' % numCC); 47 | 48 | 49 | main() 50 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/dfs_cc_in.txt: -------------------------------------------------------------------------------- 1 | 9 2 | 1 1 0 3 | 3 0 0 2 0 3 0 4 | 2 1 0 3 0 5 | 3 1 0 2 0 4 0 6 | 1 3 0 7 | 0 8 | 2 7 0 8 0 9 | 1 6 0 10 | 1 6 0 11 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/scc_in.txt: -------------------------------------------------------------------------------- 1 | 8 2 | 1 1 0 3 | 1 3 0 4 | 1 1 0 5 | 2 2 0 4 0 6 | 1 5 0 7 | 1 7 0 8 | 1 4 0 9 | 1 6 0 10 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/toposort.ml: -------------------------------------------------------------------------------- 1 | open Scanf 2 | open Printf 3 | 4 | type graph = int list array (* Adjacency List representation *) 5 | 6 | (** Return a topological ordering of the DAG *) 7 | let topo_sort (adj : graph) : int list = 8 | let n = Array.length adj in 9 | let visited = Array.make n false in 10 | let rec visit order u = 11 | visited.(u) <- true; 12 | u :: 13 | (adj.(u) |> List.fold_left (fun order v -> 14 | if visited.(v) then order 15 | else visit order v 16 | ) order) 17 | in 18 | List.init n (fun x -> x) |> List.fold_left (fun acc u -> 19 | if visited.(u) then acc 20 | else visit acc u 21 | ) [] 22 | 23 | let () = 24 | let ic = Scanning.open_in "toposort_in.txt" in 25 | let sc = object method nf = bscanf ic end in 26 | let n = sc#nf " %d " (fun x -> x) in 27 | let adj = Array.init n (fun _ -> 28 | sc#nf " %d " (fun degree -> 29 | List.init degree (fun _ -> sc#nf " %d %d " (fun v w -> v))) (* Ignoring weight *) 30 | ) in 31 | printf "Topological Sort (the input graph must be DAG)\n"; 32 | topo_sort adj |> List.iter (printf " %d"); printf "\n"; 33 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/toposort.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from enum import Enum 3 | 4 | class flag(Enum): 5 | UNVISITED = -1 6 | VISITED = -2 7 | 8 | AL = [] 9 | dfs_num = [] 10 | ts = [] 11 | 12 | def toposort(u): 13 | global AL 14 | global dfs_num 15 | global ts 16 | 17 | dfs_num[u] = flag.VISITED.value 18 | for v, w in AL[u]: 19 | if dfs_num[v] == flag.UNVISITED.value: 20 | toposort(v) 21 | ts.append(u) 22 | 23 | 24 | def main(): 25 | global AL 26 | global dfs_num 27 | global ts 28 | 29 | fp = open('toposort_in.txt', 'r') 30 | 31 | V = int(fp.readline().strip()) 32 | AL = [[] for _ in range(V)] 33 | for u in range(V): 34 | tkn = list(map(int, fp.readline().strip().split())) 35 | k = tkn[0] 36 | for i in range(k): 37 | v, w = tkn[2*i+1], tkn[2*i+2] 38 | AL[u].append((v, w)) 39 | 40 | print('Topological Sort (the input graph must be DAG)') 41 | dfs_num = [flag.UNVISITED.value] * V 42 | for u in range(V): 43 | if dfs_num[u] == flag.UNVISITED.value: 44 | toposort(u) 45 | ts = ts[::-1] 46 | print(' '.join(map(str, ts))) 47 | 48 | 49 | main() 50 | -------------------------------------------------------------------------------- /cpbook-code/ch4/traversal/toposort_in.txt: -------------------------------------------------------------------------------- 1 | 8 2 | 2 1 0 2 0 3 | 2 2 0 3 0 4 | 2 3 0 5 0 5 | 1 4 0 6 | 0 7 | 0 8 | 0 9 | 1 6 0 10 | -------------------------------------------------------------------------------- /cpbook-code/ch5/UVa00350.cpp: -------------------------------------------------------------------------------- 1 | // Pseudo-Random Numbers 2 | 3 | #include 4 | using namespace std; 5 | 6 | typedef pair ii; 7 | 8 | int Z, I, M; 9 | 10 | int f(int x) { return (Z*x + I) % M; } 11 | 12 | ii floydCycleFinding(int x0) { // f(x) is defined above 13 | // 1st part: finding k*mu, hare h's speed is 2x tortoise t's 14 | int t = f(x0), h = f(f(x0)); // f(x0) is after x0 15 | while (t != h) { t = f(t); h = f(f(h)); } 16 | // 2nd part: finding mu, hare h and tortoise t move at the same speed 17 | int mu = 0; h = x0; 18 | while (t != h) { t = f(t); h = f(h); ++mu; } 19 | // 3rd part: finding lambda, hare h moves, tortoise t stays 20 | int lambda = 1; h = f(t); 21 | while (t != h) { h = f(h); ++lambda; } 22 | return {mu, lambda}; 23 | } 24 | 25 | int main() { 26 | freopen("in.txt", "r", stdin); 27 | int caseNo = 0, L; 28 | while (scanf("%d %d %d %d", &Z, &I, &M, &L), (Z || I || M || L)) { 29 | auto [mu, lambda] = floydCycleFinding(L); 30 | printf("Case %d: %d\n", ++caseNo, lambda); 31 | return 0; 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /cpbook-code/ch5/UVa00350.java: -------------------------------------------------------------------------------- 1 | // Pseudo-Random Numbers, 0.288s in Java, 0.022s in C++ 2 | 3 | import java.util.*; 4 | 5 | class Main { 6 | static int Z, I, M, L, mu, lambda; 7 | 8 | static int f(int x) { return (Z * x + I) % M; } 9 | 10 | static void floydCycleFinding(int x0) { // function "int f(int x)" must be defined earlier 11 | // 1st part: finding k*mu, hare's speed is 2x tortoise's 12 | int tortoise = f(x0), hare = f(f(x0)); // f(x0) is the node next to x0 13 | while (tortoise != hare) { tortoise = f(tortoise); hare = f(f(hare)); } 14 | // 2nd part: finding mu, hare and tortoise move at the same speed 15 | mu = 0; hare = x0; 16 | while (tortoise != hare) { tortoise = f(tortoise); hare = f(hare); mu++; } 17 | // 3rd part: finding lambda, hare moves, tortoise stays 18 | lambda = 1; hare = f(tortoise); 19 | while (tortoise != hare) { hare = f(hare); lambda++; } 20 | } 21 | 22 | public static void main(String[] args) { 23 | Scanner sc = new Scanner(System.in); 24 | for (int caseNo = 1; ; caseNo++) { 25 | Z = sc.nextInt(); 26 | I = sc.nextInt(); 27 | M = sc.nextInt(); 28 | L = sc.nextInt(); 29 | if (Z == 0 && I == 0 && M == 0 && L == 0) break; 30 | floydCycleFinding(L); 31 | System.out.printf("Case %d: %d\n", caseNo, lambda); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /cpbook-code/ch5/UVa00350.ml: -------------------------------------------------------------------------------- 1 | (* Pseudo-Random Numbers *) 2 | open Scanf 3 | open Printf 4 | 5 | let z = ref 0 6 | let i = ref 0 7 | let m = ref 0 8 | 9 | let f x = (!z * x + !i) mod !m 10 | 11 | let floydCycleFinding x0 = (* function int f(int x) is defined earlier *) 12 | (* 1st part: finding k*mu, hare's speed is 2x tortoise's *) 13 | let tortoise = ref (f x0) and hare = ref (f (f x0)) in 14 | while !tortoise <> !hare do 15 | tortoise := f !tortoise; 16 | hare := f (f !hare) 17 | done; 18 | (* 2nd part: finding mu, hare and tortoise move at the same speed *) 19 | let mu = ref 0 in 20 | hare := x0; 21 | while !tortoise <> !hare do 22 | tortoise := f !tortoise; 23 | hare := f !hare; 24 | incr mu 25 | done; 26 | (* 3rd part: finding lambda, hare moves, tortoise stays *) 27 | let lambda = ref 1 in 28 | hare := f !tortoise; 29 | while !tortoise <> !hare do 30 | hare := f !hare; 31 | incr lambda 32 | done; 33 | (!mu, !lambda) 34 | 35 | let () = 36 | let case = ref 1 in 37 | let rec solve () = 38 | scanf "%d %d %d %d" (fun zz ii mm l -> 39 | if zz lor ii lor mm lor l > 0 then begin 40 | z := zz; i := ii; m := mm; 41 | let (_, ans) = floydCycleFinding l in 42 | printf "Case %d: %d\n" !case ans; 43 | incr case; 44 | scanf "\n" (); 45 | solve () 46 | end 47 | ) 48 | in 49 | solve () 50 | 51 | -------------------------------------------------------------------------------- /cpbook-code/ch5/UVa00350.py: -------------------------------------------------------------------------------- 1 | # Pseudo-Random Numbers, 0.288s in Java, 0.022s in C++, 0.160s in Python 2 | 3 | Z = I = M = L = -1 4 | 5 | def f(x): 6 | global Z, I, M, L 7 | return (Z * x + I) % M 8 | 9 | def floydCycleFinding(x0): 10 | # 1st part: finding k*mu, hare's speed is 2x tortoise's 11 | tortoise = f(x0) # f(x0) is the node next to x0 12 | hare = f(f(x0)) 13 | while (not tortoise == hare): 14 | tortoise = f(tortoise) 15 | hare = f(f(hare)) 16 | 17 | # 2nd part: finding mu, hare and tortoise move at the same speed 18 | mu = 0 19 | hare = x0 20 | while (not tortoise == hare): 21 | tortoise = f(tortoise) 22 | hare = f(hare) 23 | mu += 1 24 | 25 | # 3rd part: finding lambda, hare moves, tortoise stays 26 | lambd = 1 27 | hare = f(tortoise) 28 | while (tortoise != hare): 29 | hare = f(hare) 30 | lambd += 1 31 | 32 | return lambd 33 | 34 | def main(): 35 | global Z, I, M, L 36 | Z, I, M, L = map(int, input().split(" ")) 37 | case = 1 38 | while not Z == 0 and not I == 0 and not M == 0 and not L == 0: 39 | print("Case {}: {}".format(case, floydCycleFinding(L))) 40 | case += 1 41 | Z, I, M, L = map(int, input().split(" ")) 42 | 43 | main() -------------------------------------------------------------------------------- /cpbook-code/ch5/UVa01230.cpp: -------------------------------------------------------------------------------- 1 | // 0.000s in C++ 2 | 3 | #include 4 | using namespace std; 5 | 6 | int mod(int a, int m) { return ((a%m)+m) % m; } // ensure positive answer 7 | 8 | int slow_modPow(int b, int p, int m) { // assume 0 <= b < m 9 | int ans = 1; 10 | for (int i = 0; i < p; ++i) // this is O(p) 11 | ans = mod(ans*b, m); // ans always in [0..m-1] 12 | return ans; 13 | } 14 | 15 | int modPow(int b, int p, int m) { // assume 0 <= b < m 16 | if (p == 0) return 1; 17 | int ans = modPow(b, p/2, m); // this is O(log p) 18 | ans = mod(ans*ans, m); // double it first 19 | if (p&1) ans = mod(ans*b, m); // *b if p is odd 20 | return ans; // ans always in [0..m-1] 21 | } 22 | 23 | int main() { 24 | ios::sync_with_stdio(false); cin.tie(NULL); 25 | // for comparison only 26 | // for (int b = 0; b <= 100; ++b) 27 | // for (int p = 0; p <= 100; ++p) 28 | // assert(slow_modPow(b, p, 997) == modPow(b, p, 997)); 29 | int c; cin >> c; 30 | while (c--) { 31 | int x, y, n; cin >> x >> y >> n; 32 | cout << modPow(x, y, n) << "\n"; 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /cpbook-code/ch5/UVa01230.java: -------------------------------------------------------------------------------- 1 | // 0.080s in Java 2 | 3 | import java.util.Scanner; 4 | import java.math.BigInteger; 5 | 6 | class Main { // UVa 01230 (LA 4104) 7 | public static void main(String[] args) { 8 | Scanner sc = new Scanner(System.in); 9 | int c = sc.nextInt(); 10 | while (c-- > 0) { 11 | BigInteger x, y, n; 12 | x = BigInteger.valueOf(sc.nextInt()); // valueOf converts 13 | y = BigInteger.valueOf(sc.nextInt()); // simple integer 14 | n = BigInteger.valueOf(sc.nextInt()); // into BigInteger 15 | System.out.println(x.modPow(y, n)); // it's in the library! 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /cpbook-code/ch5/UVa01230.py: -------------------------------------------------------------------------------- 1 | # 0.000s in Python 2 | 3 | def main(): 4 | N = int(input()) 5 | for i in range(N): 6 | x, y, z = map(int, input().split()) 7 | print(pow(x, y, z)) 8 | main() -------------------------------------------------------------------------------- /cpbook-code/ch5/UVa10229.ml: -------------------------------------------------------------------------------- 1 | (* Modular Fibonacci *) 2 | 3 | open Printf 4 | open Scanf 5 | 6 | let max_n = 2 (* increase this if needed *) 7 | let mask = ref 0 8 | 9 | let mat_id = (* prepare identity matrix *) 10 | Array.init max_n @@ fun i -> 11 | Array.init max_n @@ fun j -> 12 | if i = j then 1 else 0 13 | 14 | let mat_fib = [| (* special matrix for Fibonacci *) 15 | [|1; 1|]; 16 | [|1; 0|] 17 | |] 18 | 19 | let mat_mul a b = (* O(n^3), but O(1) as n = 2 *) 20 | let ans = Array.make_matrix max_n max_n 0 in 21 | for i = 0 to max_n - 1 do 22 | for j = 0 to max_n - 1 do 23 | for k = 0 to max_n - 1 do 24 | ans.(i).(j) <- (ans.(i).(j) + a.(i).(k) * b.(k).(j)) land !mask 25 | done 26 | done 27 | done; 28 | ans 29 | 30 | let mat_pow base p = (* O(n^3 log p), but O(log p) as n = 2 *) 31 | let rec aux base p acc = 32 | if p = 0 then acc 33 | else 34 | let acc = if p land 1 = 1 then mat_mul acc base else acc in 35 | let base = mat_mul base base in (* square the base *) 36 | let p = p lsr 1 in (* divide p by 2 *) 37 | aux base p acc 38 | in 39 | aux base p mat_id 40 | 41 | let () = 42 | try 43 | while true do 44 | let n, m = scanf "%d %d\n" (fun x y -> x, y) in 45 | mask := 1 lsl m - 1; 46 | let ans = mat_pow mat_fib n in (* O(log n) *) 47 | printf "%d\n" ans.(0).(1) 48 | done 49 | with End_of_file -> () 50 | -------------------------------------------------------------------------------- /cpbook-code/ch5/UVa10229.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | MOD = 1 4 | 5 | def mod(a, m): 6 | return (a%m+m)%m 7 | 8 | def matMul(a, b): 9 | global MOD 10 | 11 | ans = [[0, 0], [0, 0]] 12 | for i in range(2): 13 | for k in range(2): 14 | if a[i][k] == 0: 15 | continue 16 | for j in range(2): 17 | ans[i][j] += mod(a[i][k], MOD) * mod(b[k][j], MOD) 18 | ans[i][j] = mod(ans[i][j], MOD) 19 | return ans 20 | 21 | def matPow(base, p): 22 | ans = [[1, 0], [0, 1]] 23 | while p != 0: 24 | if p&1 != 0: 25 | ans = matMul(ans, base) 26 | base = matMul(base, base) 27 | p >>= 1 28 | return ans 29 | 30 | 31 | if __name__ == '__main__': 32 | for line in sys.stdin: 33 | n, m = map(int, line.strip('\n').split()) 34 | MOD = 2**m 35 | ans = matPow([[1, 1], [1, 0]], n) 36 | print(ans[0][1]) 37 | -------------------------------------------------------------------------------- /cpbook-code/ch5/UVa10814.java: -------------------------------------------------------------------------------- 1 | // 0.212s in Java 2 | 3 | import java.util.Scanner; 4 | import java.math.BigInteger; 5 | 6 | class Main { 7 | public static void main(String[] args) { 8 | Scanner sc = new Scanner(System.in); 9 | int N = sc.nextInt(); 10 | while (N-- > 0) { // we have to use > 0 11 | BigInteger p = sc.nextBigInteger(); 12 | String ch = sc.next(); // ignore this char 13 | BigInteger q = sc.nextBigInteger(); 14 | BigInteger gcd_pq = p.gcd(q); // wow :) 15 | System.out.println(p.divide(gcd_pq) + " / " + q.divide(gcd_pq)); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /cpbook-code/ch5/UVa10814.py: -------------------------------------------------------------------------------- 1 | # 0.040s in Python 2 | 3 | from fractions import Fraction # Python's built in fractions module 4 | 5 | def main(): 6 | N = int(input()) 7 | for _ in range(N): 8 | frac = Fraction("".join(input().split(" "))) 9 | print(str(frac.numerator) + " / " + str(frac.denominator)) 10 | 11 | main() 12 | -------------------------------------------------------------------------------- /cpbook-code/ch5/basicremains_UVa10551.java: -------------------------------------------------------------------------------- 1 | // 0.345s in Java 2 | 3 | import java.util.Scanner; 4 | import java.math.BigInteger; 5 | 6 | class Main { 7 | public static void main(String[] args) { 8 | Scanner sc = new Scanner(System.in); // a few test cases 9 | while (true) { 10 | int b = sc.nextInt(); if (b == 0) break; 11 | BigInteger p = new BigInteger(sc.next(), b); // 2nd parameter 12 | BigInteger m = new BigInteger(sc.next(), b); // is the base 13 | System.out.println((p.mod(m)).toString(b)); // print in base b 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /cpbook-code/ch5/combinatorics.py: -------------------------------------------------------------------------------- 1 | MAX_N = 100010 2 | p = 10**9+7 3 | 4 | def mod(a, m): 5 | return ((a % m) + m) % m 6 | 7 | 8 | def modPow(b, p, m): 9 | if p == 0: 10 | return 1 11 | ans = modPow(b, p//2, m) 12 | ans = mod(ans*ans, m) 13 | if p % 2 == 1: 14 | ans = mod(ans*b, m) 15 | return ans 16 | 17 | 18 | def inv(a): 19 | return modPow(a, p-2, p) 20 | 21 | 22 | fact = [] 23 | invFact = [] 24 | 25 | def C(n, k): 26 | global fact, invFact 27 | 28 | if n < k: 29 | return 0 30 | return (((fact[n] * inv(fact[k])) % p) * inv(fact[n-k])) % p 31 | 32 | 33 | def main(): 34 | global fact, invFact 35 | 36 | Fib = [0] * MAX_N 37 | Fib[0] = 0 38 | Fib[1] = 1 39 | 40 | for i in range(2, MAX_N): 41 | Fib[i] = (Fib[i-1] + Fib[i-2]) % p 42 | print(Fib[100000]) 43 | 44 | fact = [0] * MAX_N 45 | invFact = [0] * MAX_N 46 | 47 | fact[0] = 1 48 | for i in range(1, MAX_N): 49 | fact[i] = (fact[i-1]*i)% p 50 | 51 | print(C(100000, 50000)) 52 | 53 | Cat = [0] * MAX_N 54 | Cat[0] = 1 55 | for n in range(MAX_N-1): 56 | Cat[n+1] = ((4*n+2)%p * Cat[n]%p * inv(n+2)) % p 57 | print(Cat[100000]) 58 | 59 | 60 | main() 61 | -------------------------------------------------------------------------------- /cpbook-code/ch5/factovisors_UVa10139.cpp: -------------------------------------------------------------------------------- 1 | // Factovisors 2 | 3 | #include 4 | using namespace std; 5 | 6 | int vp(int p, int n) { // Legendre's formula 7 | int ans = 0; 8 | for (int pi = p; pi <= n; pi *= p) 9 | ans += n/pi; // floor by default 10 | return ans; 11 | } 12 | 13 | int main() { 14 | int n, m; 15 | while (scanf("%d %d", &n, &m) != EOF) { 16 | bool possible; 17 | if (m == 0) possible = false; // special case 18 | else if (m <= n) possible = true; // always true 19 | else { // factorize m 20 | unordered_map factor_m; // in any order 21 | int temp = m; 22 | int PF = 2; 23 | while ((temp > 1) && ((long long)PF*PF <= m)) { 24 | int freq = 0; 25 | while (temp%PF == 0) { // take out this factor 26 | ++freq; 27 | temp /= PF; 28 | } 29 | if (freq > 0) factor_m[PF] = freq; 30 | ++PF; // next factor 31 | } 32 | if (temp > 1) factor_m[temp] = 1; 33 | 34 | possible = true; 35 | for (auto &[p, e] : factor_m) // for each p^e in m 36 | if (vp(p, n) < e) { // has support in n!? 37 | possible = false; // ups, not enough 38 | break; 39 | } 40 | } 41 | 42 | printf("%d %s %d!\n", m, possible ? "divides" : "does not divide", n); 43 | } 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /cpbook-code/ch5/factovisors_UVa10139.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | def vp(p, n): # Legendre's formula 4 | ans = 0 5 | pi = p 6 | while pi <= n: 7 | ans += n//pi # floor by default 8 | pi *= p 9 | return ans 10 | 11 | def main(): 12 | for line in sys.stdin: 13 | n,m = map(int, line.split()) 14 | possible = True 15 | if m == 0: # special case 16 | possible = False 17 | elif m <= n: # always true 18 | possible = True 19 | else: # factorize m 20 | factor_m = dict(); # in any order 21 | temp = m 22 | PF = 2 23 | while temp > 1 and PF*PF <= m: 24 | freq = 0 25 | while temp%PF == 0: # take out this factor 26 | freq += 1 27 | temp /= PF 28 | if freq > 0: 29 | factor_m[PF] = freq 30 | PF += 1 # next factor 31 | if temp > 1: 32 | factor_m[temp] = 1 33 | 34 | possible = True 35 | for p, e in factor_m.items(): # for each p^e in m 36 | if vp(p, n) < e: # has support in n!? 37 | possible = False # ups, not enough 38 | break 39 | 40 | print("{} {} {}!".format(m, ("divides" if possible else "does not divide"), n)) 41 | 42 | main() 43 | -------------------------------------------------------------------------------- /cpbook-code/ch5/modInverse.py: -------------------------------------------------------------------------------- 1 | def mod(a, m): 2 | return ((a % m) + m) % m 3 | 4 | 5 | def modPow(b, p, m): 6 | if p == 0: 7 | return 1 8 | ans = modPow(b, p//2, m) 9 | ans = mod(ans*ans, m) 10 | if p % 2 == 1: 11 | ans = mod(ans*b, m) 12 | return ans 13 | 14 | 15 | def extEuclid(a, b): 16 | xx, yy = 0, 1 17 | x, y = 1, 0 18 | while b != 0: 19 | q = a//b 20 | a, b = b, a%b 21 | x, xx = xx, x-q*xx 22 | y, yy = yy, y-q*yy 23 | return a, x, y 24 | 25 | 26 | def modInverse(b, m): 27 | d, x, y = extEuclid(b, m) 28 | if d != 1: 29 | return -1 30 | return mod(x, m) 31 | 32 | 33 | def main(): 34 | print('%d' % ((27%7 * modPow(3, 5, 7)) % 7)) 35 | print('%d' % ((27%7 * modPow(4, 5, 7)) % 7)) 36 | print('%d' % ((520%18 * modPow(25, 16, 18)) % 18)) 37 | 38 | print('%d' % ((27%7 * modInverse(3, 7)) % 7)) 39 | print('%d' % ((27%7 * modInverse(4, 7)) % 7)) 40 | print('%d' % ((520%18 * modInverse(25, 18)) % 18)) 41 | 42 | 43 | main() 44 | -------------------------------------------------------------------------------- /cpbook-code/ch6/Trie.py: -------------------------------------------------------------------------------- 1 | class vertex: 2 | def __init__(self, chr: str): 3 | self.alphabet = chr 4 | self.exist = False 5 | self.child = [None] * 26 6 | 7 | class Trie: 8 | def __init__(self): 9 | self.root = vertex('!') 10 | 11 | def insert(self, word): 12 | cur = self.root 13 | for w in word: 14 | alphaNum = ord(w)-ord('A') 15 | if cur.child[alphaNum] == None: 16 | cur.child[alphaNum] = vertex(w) 17 | cur = cur.child[alphaNum] 18 | cur.exist = True 19 | 20 | def search(self, word): 21 | cur = self.root 22 | for w in word: 23 | alphaNum = ord(w)-ord('A') 24 | if cur.child[alphaNum] == None: 25 | return False 26 | cur = cur.child[alphaNum] 27 | return cur.exist 28 | 29 | def startsWith(self, prefix): 30 | cur = self.root 31 | for w in prefix: 32 | alphaNum = ord(w)-ord('A') 33 | if cur.child[alphaNum] == None: 34 | return False 35 | cur = cur.child[alphaNum] 36 | return True 37 | 38 | 39 | def main(): 40 | T = Trie() 41 | S = ['CAR', 'CAT', 'RAT'] 42 | for s in S: 43 | print('Insert', s) 44 | T.insert(s) 45 | 46 | print('\'CAR\' exist?', T.search("CAR")) 47 | print('\'DOG\' exist?', T.search("DOG")) 48 | print('Starts with \'CA\' exist?', T.startsWith("CA")) 49 | print('Starts with \'Z\' exist?', T.startsWith("Z")) 50 | print('Starts with \'AT\' exist?', T.startsWith("AT")) 51 | 52 | 53 | main() 54 | -------------------------------------------------------------------------------- /cpbook-code/ch6/sa_lcp_in.txt: -------------------------------------------------------------------------------- 1 | CATUCATU 2 | -------------------------------------------------------------------------------- /cpbook-code/ch6/sa_lcp_slow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | typedef vector vi; 5 | 6 | const int MAX_N = 2510; // O(n^2 log n) 7 | 8 | char T[MAX_N]; // up to 2500 chars 9 | 10 | int main() { 11 | freopen("sa_lcp_in.txt", "r", stdin); 12 | scanf("%s", &T); // read T 13 | int n = (int)strlen(T); // count n 14 | T[n++] = '$'; // add terminating symbol 15 | 16 | vi SA(n); 17 | iota(SA.begin(), SA.end(), 0); // the initial SA 18 | // analysis of this sort below: O(n log n) * cmp: O(n) = O(n^2 log n) 19 | sort(SA.begin(), SA.end(), [](int a, int b) { // O(n^2 log n) 20 | return strcmp(T+a, T+b) < 0; 21 | }); // continued below 22 | 23 | vi LCP(n); 24 | LCP[0] = 0; // default value 25 | for (int i = 1; i < n; ++i) { // compute by def, O(n^2) 26 | int L = 0; // always reset L to 0 27 | while ((SA[i]+L < n) && (SA[i-1]+L < n) && 28 | (T[SA[i]+L] == T[SA[i-1]+L])) ++L; // same L-th char, ++L 29 | LCP[i] = L; 30 | } 31 | 32 | printf("T = '%s'\n", T); 33 | printf(" i SA[i] LCP[i] Suffix SA[i]\n"); 34 | for (int i = 0; i < n; ++i) 35 | printf("%2d %2d %2d %s\n", i, SA[i], LCP[i], T+SA[i]); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /cpbook-code/ch6/string_alignment.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main() { 7 | char A[20] = "ACAATCC", B[20] = "AGCATGC"; 8 | int n = (int)strlen(A), m = (int)strlen(B); 9 | int i, j, table[20][20]; // Needleman Wunsnch's algorithm 10 | 11 | memset(table, 0, sizeof table); 12 | // insert/delete = -1 point 13 | for (i = 1; i <= n; i++) 14 | table[i][0] = i * -1; 15 | for (j = 1; j <= m; j++) 16 | table[0][j] = j * -1; 17 | 18 | for (i = 1; i <= n; i++) 19 | for (j = 1; j <= m; j++) { 20 | // match = 2 points, mismatch = -1 point 21 | table[i][j] = table[i - 1][j - 1] + (A[i - 1] == B[j - 1] ? 2 : -1); // cost for match or mismatches 22 | // insert/delete = -1 point 23 | table[i][j] = max(table[i][j], table[i - 1][j] - 1); // delete 24 | table[i][j] = max(table[i][j], table[i][j - 1] - 1); // insert 25 | } 26 | 27 | printf("DP table:\n"); 28 | for (i = 0; i <= n; i++) { 29 | for (j = 0; j <= m; j++) 30 | printf("%3d", table[i][j]); 31 | printf("\n"); 32 | } 33 | printf("Maximum Alignment Score: %d\n", table[n][m]); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /cpbook-code/ch6/string_alignment.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class string_alignment { 4 | public static void main(String[] args){ 5 | char[] A = "ACAATCC".toCharArray(), B = "AGCATGC".toCharArray(); 6 | int[][] table = new int[20][20]; // Needleman Wunsnch's algorithm 7 | int n = A.length, m = B.length; 8 | 9 | // insert/delete = -1 point 10 | for (int i = 1; i <= n; ++i) 11 | table[i][0] = i * -1; 12 | for (int j = 1; j <= m; ++j) 13 | table[0][j] = j * -1; 14 | 15 | for (int i = 1; i <= n; ++i) 16 | for (int j = 1; j <= m; ++j) { 17 | // match = 2 points, mismatch = -1 point 18 | table[i][j] = table[i - 1][j - 1] + (A[i - 1] == B[j - 1] ? 2 : -1); // cost for match or mismatches 19 | // insert/delete = -1 point 20 | table[i][j] = Math.max(table[i][j], table[i - 1][j] - 1); // delete 21 | table[i][j] = Math.max(table[i][j], table[i][j - 1] - 1); // insert 22 | } 23 | 24 | System.out.printf("DP table:\n"); 25 | for (int i = 0; i <= n; ++i) { 26 | for (int j = 0; j <= m; ++j) 27 | System.out.printf("%3d", table[i][j]); 28 | System.out.printf("\n"); 29 | } 30 | System.out.printf("Maximum Alignment Score: %d\n", table[n][m]); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /cpbook-code/ch6/string_alignment.ml: -------------------------------------------------------------------------------- 1 | module S = String 2 | 3 | let compute_table a b = 4 | let n = S.length a in 5 | let m = S.length b in 6 | let table = Array.make_matrix (n+1) (m+1) 0 in 7 | (* insert/delete = -1 point *) 8 | for i = 1 to n do 9 | table.(i).(0) <- i * (-1) 10 | done; 11 | for j = 1 to m do 12 | table.(0).(j) <- j * (-1) 13 | done; 14 | for i = 1 to n do 15 | for j = 1 to m do 16 | (* match = 2 points, mismatch = -1 point *) 17 | table.(i).(j) <- 18 | max (table.(i-1).(j-1) + if a.[i-1] = b.[j-1] then 2 else -1) 19 | (-1 + max table.(i-1).(j) table.(i).(j-1)) (* insert/delete *) 20 | done 21 | done; 22 | table 23 | 24 | let () = 25 | let a = "ACAATCC" in 26 | let b = "AGCATGC" in 27 | let table = compute_table a b in 28 | let open Printf in 29 | printf "DP table:\n"; 30 | table |> Array.iter (fun row -> 31 | row |> Array.iter (printf "%3d"); 32 | printf "\n" 33 | ); 34 | printf "Maximum Alignment Score: %d\n" table.(S.length a).(S.length b) -------------------------------------------------------------------------------- /cpbook-code/ch6/string_alignment.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | A = "ACAATCC" 3 | B = "AGCATGC" 4 | n = len(A) 5 | m = len(B) 6 | 7 | table = [[0 for j in range(20)] for i in range(20)] # Needleman Wunsnch's algorithm 8 | 9 | for i in range(1, n+1): 10 | table[i][0] = i * -1 11 | for j in range(1, m+1): 12 | table[0][j] = j * -1 13 | 14 | for i in range(1, n+1): 15 | for j in range(1, m+1): 16 | # match = 2 points, mismatch = -1 point 17 | table[i][j] = table[i - 1][j - 1] + (2 if A[i - 1] == B[j - 1] else -1) 18 | # insert/delete = -1 point 19 | table[i][j] = max(table[i][j], table[i - 1][j] - 1); # delete 20 | table[i][j] = max(table[i][j], table[i][j - 1] - 1); # insert 21 | 22 | print("DP table:") 23 | for i in range(0, n+1): 24 | for j in range(0, m+1): 25 | print("{:>3}".format(table[i][j]), end='') 26 | print() 27 | 28 | print("Maximum Alignment Score: {}".format(table[n][m])) 29 | 30 | main() 31 | -------------------------------------------------------------------------------- /cpbook-code/ch6/string_matching.ml: -------------------------------------------------------------------------------- 1 | let failure_function pattern = 2 | let m = String.length pattern in 3 | let fail = Array.make (m + 1) (-1) in 4 | let i, j = ref 0, ref (-1) in 5 | while !i < m do 6 | while !j >= 0 && pattern.[!i] <> pattern.[!j] do 7 | j := fail.(!j) 8 | done; 9 | incr i; incr j; 10 | fail.(!i) <- !j 11 | done; 12 | fail 13 | 14 | let kmp_search text pattern fail = 15 | let n = String.length text in 16 | let m = String.length pattern in 17 | let i, j = ref 0, ref 0 in 18 | let matches = ref [] in 19 | while !i < n do 20 | while !j >= 0 && text.[!i] <> pattern.[!j] do 21 | j := fail.(!j) 22 | done; 23 | incr i; incr j; 24 | if !j = m then begin 25 | matches := !i - !j :: !matches; 26 | j := fail.(!j) 27 | end 28 | done; 29 | !matches |> List.rev 30 | 31 | let () = 32 | let text = "I DO NOT LIKE SEVENTY SEV BUT SEVENTY SEVENTY SEVEN" in 33 | let pattern = "SEVENTY SEVEN" in 34 | let fail = failure_function pattern in 35 | kmp_search text pattern fail 36 | |> List.iter (Printf.printf "P is found at index %d in T\n") 37 | 38 | (* Rabin Karp's will be added soon *) 39 | -------------------------------------------------------------------------------- /cpbook-code/ch7/UVa11817.py: -------------------------------------------------------------------------------- 1 | from math import cos, acos, sin, asin, pi, sqrt 2 | 3 | EARTH_RAD = 6371009 4 | 5 | def gcDistance(pLat, pLong, qLat, qLong, radius): 6 | pLat *= pi / 180 7 | pLong *= pi / 180 8 | qLat *= pi / 180 9 | qLong *= pi / 180 10 | return radius * acos(cos(pLat)*cos(pLong)*cos(qLat)*cos(qLong) +\ 11 | cos(pLat)*sin(pLong)*cos(qLat)*sin(qLong) +\ 12 | sin(pLat)*sin(qLat)) 13 | 14 | 15 | def EuclideanDistance(pLat, pLong, qLat, qLong, radius): 16 | phi1 = (90 - pLat) * pi / 180 17 | theta1 = (360 - pLong) * pi / 180 18 | x1 = radius * sin(phi1) * cos(theta1) 19 | y1 = radius * sin(phi1) * sin(theta1) 20 | z1 = radius * cos(phi1) 21 | 22 | phi2 = (90 - qLat) * pi / 180 23 | theta2 = (360 - qLong) * pi / 180 24 | x2 = radius * sin(phi2) * cos(theta2) 25 | y2 = radius * sin(phi2) * sin(theta2) 26 | z2 = radius * cos(phi2) 27 | 28 | dx = x1 - x2 29 | dy = y1 - y2 30 | dz = z1 - z2 31 | return sqrt(dx * dx + dy * dy + dz * dz) 32 | 33 | 34 | def main(): 35 | TC = int(input()) 36 | for _ in range(TC): 37 | lat1, lon1, lat2, lon2 = map(float, input().split()) 38 | print('%.lf' % (gcDistance(lat1, lon1, lat2, lon2, EARTH_RAD) -\ 39 | EuclideanDistance(lat1, lon1, lat2, lon2, EARTH_RAD))) 40 | 41 | 42 | main() 43 | -------------------------------------------------------------------------------- /cpbook-code/ch8/UVa01231.cpp: -------------------------------------------------------------------------------- 1 | // ACORN, UVa 1231, LA 4106 2 | 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | int i, j, c, t, h, f, a, n, acorn[2010][2010], dp[2010]; 10 | 11 | scanf("%d", &c); 12 | while (c--) { 13 | scanf("%d %d %d", &t, &h, &f); 14 | memset(acorn, 0, sizeof acorn); 15 | for (i = 0; i < t; i++) { 16 | scanf("%d", &a); 17 | for (j = 0; j < a; j++) { 18 | scanf("%d", &n); 19 | acorn[i][n]++; // there is an acorn here 20 | } 21 | } 22 | 23 | for (int tree = 0; tree < t; tree++) // initialization 24 | dp[h] = max(dp[h], acorn[tree][h]); 25 | for (int height = h - 1; height >= 0; height--) 26 | for (int tree = 0; tree < t; tree++) { 27 | acorn[tree][height] += 28 | max(acorn[tree][height + 1], // from this tree, +1 above 29 | ((height + f <= h) ? dp[height + f] : 0)); // best from tree at height + f 30 | dp[height] = max(dp[height], acorn[tree][height]); // update this too 31 | } 32 | printf("%d\n", dp[0]); // solution will be here 33 | } 34 | // ignore the last number 0 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /cpbook-code/ch8/UVa01231.java: -------------------------------------------------------------------------------- 1 | // ACORN, UVa 1231, LA 4106, 0.???s in Java (submission error?), 0.344s in C++ 2 | 3 | import java.util.*; 4 | 5 | class UVa01231 { 6 | public static void main(String[] args) { 7 | int i, j, c, t, h, f, a, n; 8 | int[][] acorn = new int[2010][2010]; 9 | int[] dp = new int[2010]; 10 | Scanner sc = new Scanner(System.in); 11 | 12 | c = sc.nextInt(); 13 | while (c-- > 0) { 14 | t = sc.nextInt(); h = sc.nextInt(); f = sc.nextInt(); 15 | for (i = 0; i < 2010; i++) 16 | for (j = 0; j < 2010; j++) 17 | acorn[i][j] = 0; 18 | for (i = 0; i < t; i++) { 19 | a = sc.nextInt(); 20 | for (j = 0; j < a; j++) { 21 | n = sc.nextInt(); 22 | acorn[i][n]++; // there is an acorn here 23 | } 24 | } 25 | 26 | for (int tree = 0; tree < t; tree++) // initialization 27 | dp[h] = Math.max(dp[h], acorn[tree][h]); 28 | for (int height = h - 1; height >= 0; height--) 29 | for (int tree = 0; tree < t; tree++) { 30 | acorn[tree][height] += 31 | Math.max(acorn[tree][height + 1], // from this tree, +1 above 32 | ((height + f <= h) ? dp[height + f] : 0)); // best from tree at height + f 33 | dp[height] = Math.max(dp[height], acorn[tree][height]); // update this too 34 | } 35 | System.out.printf("%d\n", dp[0]); // solution will be here 36 | } 37 | // ignore the last number 0 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /cpbook-code/ch8/UVa01231.ml: -------------------------------------------------------------------------------- 1 | (* ACORN *) 2 | 3 | open Scanf 4 | open Printf 5 | 6 | let solve t h f = 7 | let acorn = Array.init 2010 (fun _ -> Array.make 2010 0) in 8 | for i = 0 to t-1 do 9 | scanf "%d" (fun a -> 10 | for j = 1 to a do 11 | scanf " %d" (fun n -> acorn.(i).(n) <- acorn.(i).(n) + 1) 12 | done 13 | ); 14 | scanf "\n" () 15 | done; 16 | let dp = Array.make 2010 0 in 17 | for tree = 0 to t-1 do dp.(h) <- max dp.(h) acorn.(tree).(h) done; 18 | for height = h-1 downto 0 do 19 | for tree = 0 to t-1 do 20 | acorn.(tree).(height) <- 21 | acorn.(tree).(height) + 22 | max acorn.(tree).(height+1) (if height + f <= h then dp.(height+f) else 0); 23 | dp.(height) <- max dp.(height) acorn.(tree).(height) 24 | done 25 | done; 26 | printf "%d\n" dp.(0) 27 | 28 | let () = 29 | scanf "%d\n" (fun c -> 30 | for case = 1 to c do 31 | scanf "%d %d %d\n" solve 32 | done 33 | ) 34 | -------------------------------------------------------------------------------- /cpbook-code/ch8/UVa01231.py: -------------------------------------------------------------------------------- 1 | if __name__ == '__main__': 2 | c = int(input()) 3 | for _ in range(c): 4 | t, h, f = map(int, input().split()) 5 | 6 | acorn = [[0] * 2010 for _ in range(2010)] 7 | dp = [0] * 2010 8 | 9 | for i in range(t): 10 | tkn = list(map(int, input().split())) 11 | a = tkn[0] 12 | for j in range(a): 13 | acorn[i][tkn[j+1]] += 1 14 | 15 | for tree in range(t): 16 | dp[h] = max(dp[h], acorn[tree][h]) 17 | for height in range(h-1, -1, -1): 18 | for tree in range(t): 19 | acorn[tree][height] += \ 20 | max(acorn[tree][height+1], dp[height+f] if height+f <= h else 0) 21 | dp[height] = max(dp[height], acorn[tree][height]) 22 | print(dp[0]) 23 | -------------------------------------------------------------------------------- /cpbook-code/ch8/UVa01238.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from functools import lru_cache 3 | 4 | sys.setrecursionlimit(1000000) 5 | 6 | num = [] 7 | sign = [] 8 | S = set() 9 | 10 | @lru_cache(maxsize=None) 11 | def dp(open, n, value): 12 | global num, sign 13 | 14 | if n == len(num)-1: 15 | S.add(value) 16 | return 17 | 18 | nval = sign[n+1] * num[n+1] * (1 if open%2 == 0 else -1) 19 | if open > 0: 20 | dp(open-1, n+1, value+nval) 21 | if sign[n+1] == -1: 22 | dp(open+1, n+1, value+nval) 23 | dp(open, n+1, value+nval) 24 | 25 | 26 | if __name__ == '__main__': 27 | for line in sys.stdin: 28 | tkn = line.strip('\n').split() 29 | 30 | sign = [1] 31 | num = [int(tkn[0])] 32 | for i in range(1, len(tkn), 2): 33 | sign.append(-1 if tkn[i] == '-' else 1) 34 | num.append(int(tkn[i+1])) 35 | 36 | S.clear() 37 | dp.cache_clear() 38 | dp(0, 0, num[0]) 39 | print(len(S)) 40 | -------------------------------------------------------------------------------- /cpbook-code/ch8/UVa10243.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from functools import lru_cache 3 | 4 | sys.setrecursionlimit(1000000) 5 | 6 | AL = [] 7 | Children = [] 8 | vis = [] 9 | 10 | def dfs(u): 11 | global AL, Children, vis 12 | 13 | vis[u] = True 14 | for v in AL[u]: 15 | if not vis[v]: 16 | Children[u].append(v) 17 | dfs(v) 18 | 19 | @lru_cache(maxsize=None) 20 | def mvc(u, flag): 21 | global AL, Children 22 | 23 | if len(Children[u]) == 0: 24 | return flag 25 | elif flag == 0: 26 | return sum([mvc(v,1) for v in Children[u]]) 27 | elif flag == 1: 28 | return 1+sum([min(mvc(v,1), mvc(v,0)) for v in Children[u]]) 29 | 30 | 31 | if __name__ == '__main__': 32 | for line in sys.stdin: 33 | N = int(line.strip('\n')) 34 | if N == 0: 35 | break 36 | AL = [list() for _ in range(N)] 37 | Children = [list() for _ in range(N)] 38 | for u in range(N): 39 | tkn = list(map(int, sys.stdin.readline().strip('\n').split())) 40 | ni = tkn[0] 41 | for i in range(1, ni+1): 42 | v = tkn[i]-1 43 | AL[u].append(v) 44 | if N == 1: 45 | print(1) 46 | continue 47 | vis = [False] * N 48 | dfs(0) 49 | mvc.cache_clear() 50 | print(min(mvc(0, 1), mvc(0, 0))) 51 | -------------------------------------------------------------------------------- /cpbook-code/ch8/UVa11065.cpp: -------------------------------------------------------------------------------- 1 | // Gentlemen Agreement 2 | 3 | #include 4 | using namespace std; 5 | 6 | const int MAX_V = 62; 7 | 8 | #define LSOne(S) ((S) & -(S)) // important speedup 9 | 10 | typedef long long ll; 11 | 12 | ll AM[MAX_V]; 13 | int V, numIS, MIS; 14 | 15 | void backtrack(int u, ll mask, int depth) { 16 | if (mask == 0) { // all have been visited 17 | ++numIS; // one more possible IS 18 | MIS = max(MIS, depth); // size of the set 19 | } 20 | else { 21 | ll m = mask; 22 | while (m) { 23 | ll two_pow_v = LSOne(m); 24 | int v = __builtin_ctzl(two_pow_v); // v is not yet used 25 | m -= two_pow_v; 26 | if (v < u) continue; // do not double count 27 | backtrack(v+1, mask & ~AM[v], depth+1); // use v + its neighbors 28 | } 29 | } 30 | } 31 | 32 | int main() { 33 | int TC; scanf("%d", &TC); 34 | while (TC--) { 35 | int E; scanf("%d %d", &V, &E); 36 | // compact AM for faster set operations 37 | for (int u = 0; u < V; ++u) 38 | AM[u] = (1LL< shift_left one i) 10 | let dpcon = Array.make maxi zero 11 | let num_v = ref 0 12 | let ns = ref 0 13 | let mxs = ref 0 14 | 15 | let rec backtracking i used depth = 16 | if used = sub (shift_left one !num_v) one then begin 17 | incr ns; 18 | mxs := max !mxs depth 19 | end else 20 | for j = i to !num_v-1 do 21 | if logand used p2.(j) = 0L 22 | then 23 | backtracking (j+1) (logor used am.(j)) (depth+1) 24 | done 25 | ;; 26 | 27 | let solve () = 28 | scanf "%d %d\n" (fun v e -> 29 | num_v := v; 30 | for i = 0 to v-1 do am.(i) <- (shift_left one i) done; 31 | for i = 1 to e do 32 | scanf "%d %d\n" (fun a b -> 33 | am.(a) <- logor am.(a) (shift_left one b); 34 | am.(b) <- logor am.(b) (shift_left one a) 35 | ) 36 | done; 37 | dpcon.(v) <- 0L; 38 | for i = v-1 downto 0 do dpcon.(i) <- logor am.(i) dpcon.(i+1) done; 39 | ns := 0; mxs := 0; 40 | backtracking 0 0L 0; 41 | printf "%d\n%d\n" !ns !mxs 42 | ) 43 | 44 | let () = 45 | scanf "%d\n" (fun tc -> 46 | for case = 1 to tc do solve () done 47 | ) 48 | 49 | 50 | -------------------------------------------------------------------------------- /cpbook-code/ch8/UVa11195.cpp: -------------------------------------------------------------------------------- 1 | // Another n-Queen Problem 2 | 3 | #include 4 | using namespace std; 5 | 6 | #define LSOne(S) ((S) & (-S)) 7 | 8 | typedef long long ll; 9 | 10 | int n, mask[32]; 11 | 12 | ll bf(int row, int col, int left_diagonal, int right_diagonal) { 13 | if (row == n) return 1; // done, 1 way found 14 | // bit = all possible column positions 15 | int bit = mask[row] | col | left_diagonal | right_diagonal; // list of forbidden column 16 | bit = ~bit; // after negation, list of allowed columns, but it turns on more bits than necessary 17 | bit &= (1<> 1, (right_diagonal|t) << 1); 23 | bit -= t; // remove that bit t from 'bit' 24 | } 25 | return total; 26 | } 27 | 28 | int main() { 29 | int caseNo = 1; 30 | char M[32]; 31 | while (scanf("%d ", &n), n) { 32 | for (int i = 0; i < n; i++) { 33 | scanf("%s ", &M); 34 | mask[i] = 0; 35 | for (int j = 0; j < n; j++) 36 | if (M[j] == '*') 37 | mask[i] |= (1< 0 do 16 | let t = ls_one !bit in 17 | total := add !total (bf (row+1) (col lor t) ((left_diag lor t) lsr 1) ((right_diag lor t) lsl 1)); 18 | bit := !bit - t 19 | done; 20 | !total 21 | 22 | let () = 23 | let case = ref 1 in 24 | let rec solve () = 25 | scanf "%d" (fun x -> 26 | n := x; 27 | if x <> 0 then begin 28 | scanf "\n" (); 29 | for i = 0 to x-1 do 30 | mask.(i) <- 0; 31 | scanf "%s\n" (fun str -> 32 | for j = 0 to x-1 do 33 | if String.get str j = '*' then mask.(i) <- mask.(i) lor (1 lsl j) 34 | done 35 | ) 36 | done; 37 | printf "Case %d: %Ld\n" !case (bf 0 0 0 0); 38 | incr case; 39 | solve () 40 | end 41 | ) 42 | in 43 | solve () 44 | -------------------------------------------------------------------------------- /cpbook-code/ch8/UVa11646.cpp: -------------------------------------------------------------------------------- 1 | // Athletics Track 2 | // see the figure in Chapter 8.7 3 | // the key = center of circle is at center of track 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | int a, b, caseNo = 0; 10 | while (scanf("%d : %d", &a, &b) != EOF) { 11 | double lo = 0.0, hi = 400.0, L, W; // the range of answer 12 | for (int i = 0; i < 40; ++i) { 13 | L = (lo+hi) / 2.0; // bisection method on L 14 | W = (double)b/a*L; // derive W from L and a:b 15 | double expected_arc = (400 - 2.0*L) / 2.0; // reference value 16 | double CM = 0.5*L, MX = 0.5*W; // Apply Trigonometry here 17 | double r = sqrt(CM*CM + MX*MX); 18 | double angle = 2.0 * atan(MX/CM) * 180.0/M_PI; 19 | double this_arc = angle/360.0 * M_PI * (2.0*r); 20 | (this_arc > expected_arc) ? hi = L : lo = L; 21 | } 22 | printf("Case %d: %.12lf %.12lf\n", ++caseNo, L, W); 23 | } 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /cpbook-code/ch8/UVa11646.java: -------------------------------------------------------------------------------- 1 | // Athletics Track 2 | // see the figure in Chapter 8.7 3 | // the key = center of circle is at center of track 4 | 5 | import java.util.*; 6 | 7 | class UVa11646 { 8 | public static void main(String[] args) { 9 | Scanner sc = new Scanner(System.in); 10 | int caseNo = 0; 11 | while (sc.hasNext()) { 12 | int a = sc.nextInt(); 13 | String ch = sc.next(); 14 | int b = sc.nextInt(); 15 | double lo = 0.0, hi = 400.0, L = 0, W = 0; // the range of answer 16 | for (int i = 0; i < 40; ++i) { 17 | L = (lo+hi) / 2.0; // bisection method on L 18 | W = (double)b/a*L; // derive W from L and a:b 19 | double expected_arc = (400 - 2.0*L) / 2.0; // reference value 20 | double CM = 0.5*L, MX = 0.5*W; // Apply Trigonometry here 21 | double r = Math.sqrt(CM*CM + MX*MX); 22 | double angle = 2.0 * Math.atan(MX/CM) * 180.0/Math.PI; 23 | double this_arc = angle/360.0 * Math.PI * (2.0*r); 24 | if (this_arc > expected_arc) 25 | hi = L; 26 | else 27 | lo = L; 28 | } 29 | System.out.printf("Case %d: %.12f %.12f\n", ++caseNo, L, W); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /cpbook-code/ch8/UVa11646.py: -------------------------------------------------------------------------------- 1 | # Athletics Track 2 | # see the figure in Chapter 8.7 3 | # the key = center of circle is at center of track 4 | 5 | import sys,math 6 | 7 | caseNo = 0 8 | for a_colon_b in sys.stdin: 9 | a,colon,b = a_colon_b.split() 10 | a = int(a) 11 | b = int(b) 12 | lo = 0.0 13 | hi = 400.0 # the range of answer 14 | for _ in range(40): 15 | L = (lo+hi) / 2.0 # bisection method on L 16 | W = b/a*L # derive W from L and a:b 17 | expected_arc = (400 - 2.0*L) / 2.0 # reference value 18 | CM = 0.5*L 19 | MX = 0.5*W # Apply Trigonometry here 20 | r = math.sqrt(CM*CM + MX*MX) 21 | angle = 2.0 * math.atan(MX/CM) * 180.0/math.pi 22 | this_arc = angle/360.0 * math.pi * (2.0*r) 23 | if this_arc > expected_arc: 24 | hi = L 25 | else: 26 | lo = L 27 | caseNo += 1 28 | print("Case {:d}: {:.12f} {:.12f}".format(caseNo, L, W)) 29 | -------------------------------------------------------------------------------- /cpbook-code/ch8/maxflow_in.txt: -------------------------------------------------------------------------------- 1 | 4 0 3 2 | 2 1 8 2 8 3 | 2 2 1 3 8 4 | 1 3 8 5 | 0 6 | -------------------------------------------------------------------------------- /cpbook-code/ch9/GaussianElimination.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | 3 | let gaussian_elimination n aug = 4 | for i = 0 to n - 1 do (* the forward elimination phase *) 5 | let l = ref i in 6 | for j = i + 1 to n - 1 do (* which row has largest column value *) 7 | if abs_float aug.(j).(i) > abs_float aug.(!l).(i) then 8 | l := j; (* remember this row l *) 9 | done; 10 | (* swap this pivot row, reason: minimize floating point error *) 11 | let t = aug.(i) in aug.(i) <- aug.(!l); aug.(!l) <- t; 12 | for j = i + 1 to n - 1 do (* the actual forward elimination phase *) 13 | for k = n downto i do 14 | aug.(j).(k) <- aug.(j).(k) -. aug.(i).(k) *. aug.(j).(i) /. aug.(i).(i) 15 | done 16 | done 17 | done; 18 | 19 | let ans = Array.create_float n in (* the back substitution phase *) 20 | for j = n - 1 downto 0 do (* start from back *) 21 | let t = ref 0. in 22 | for k = j + 1 to n - 1 do 23 | t := !t +. aug.(j).(k) *. ans.(k) 24 | done; 25 | ans.(j) <- (aug.(j).(n) -. !t) /. aug.(j).(j) (* the answer is here *) 26 | done; 27 | ans 28 | 29 | let () = 30 | let aug = [| 31 | [|1.; 1.; 2.; 9.|]; 32 | [|2.; 4.; -3.; 1.|]; 33 | [|3.; 6.; -5.; 0.|]; 34 | |] in 35 | let x = gaussian_elimination 3 aug in 36 | printf "X = %.1f, Y = %.1f, Z = %.1f\n" x.(0) x.(1) x.(2) 37 | -------------------------------------------------------------------------------- /cpbook-code/ch9/GaussianElimination.py: -------------------------------------------------------------------------------- 1 | def GaussianElimination(N, mat): 2 | for i in range(N-1): 3 | l = i 4 | for j in range(i+1, N): 5 | if abs(mat[j][i]) > abs(mat[l][i]): 6 | l = j 7 | for k in range(i, N+1): 8 | mat[i][k], mat[l][k] = mat[l][k], mat[i][k] 9 | for j in range(i+1, N): 10 | for k in range(N, i-1, -1): 11 | mat[j][k] -= mat[i][k] * mat[j][i] / mat[i][i] 12 | 13 | ans = [0] * N 14 | for j in range(N-1, -1, -1): 15 | t = 0.0 16 | for k in range(j+1, N): 17 | t += mat[j][k] * ans[k] 18 | ans[j] = (mat[j][N]-t) / mat[j][j] 19 | 20 | return ans 21 | 22 | 23 | def main(): 24 | mat = [None] * 3 25 | mat[0] = [1, 1, 2, 9] 26 | mat[1] = [2, 4, -3, 1] 27 | mat[2] = [3, 6, -5, 0] 28 | 29 | X = GaussianElimination(3, mat) 30 | print('X = %.1lf, Y = %.1lf, Z = %.1lf' % (X[0], X[1], X[2])) 31 | 32 | 33 | main() 34 | -------------------------------------------------------------------------------- /cpbook-code/ch9/HLD.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | sys.setrecursionlimit(5000) 4 | 5 | AL = [] 6 | par = [] 7 | heavy = [] 8 | group = [] 9 | 10 | def heavy_light(x): 11 | global AL, par, heavy 12 | 13 | size = 1 14 | max_child_size = 0 15 | for y in AL[x]: 16 | if y == par[x]: 17 | continue 18 | par[y] = x 19 | child_size = heavy_light(y) 20 | if child_size > max_child_size: 21 | max_child_size = child_size 22 | heavy[x] = y 23 | size += child_size 24 | return size 25 | 26 | def decompose(x, p): 27 | global AL, par, heavy, group 28 | 29 | group[x] = p 30 | for y in AL[x]: 31 | if y == par[x]: 32 | continue 33 | if y == heavy[x]: 34 | decompose(y, p) 35 | else: 36 | decompose(y, y) 37 | 38 | 39 | def main(): 40 | global AL, par, heavy, group 41 | 42 | N = 19 43 | AL = [None] * N 44 | AL[0] = [1, 2, 3] 45 | AL[1] = [0, 4] 46 | AL[2] = [0, 5, 6, 7] 47 | AL[3] = [0, 8] 48 | AL[4] = [1, 9, 10] 49 | AL[5] = [2] 50 | AL[6] = [2] 51 | AL[7] = [2, 11, 12] 52 | AL[8] = [3] 53 | AL[9] = [4] 54 | AL[10] = [4, 13] 55 | AL[11] = [7, 14] 56 | AL[12] = [7, 15] 57 | AL[13] = [10] 58 | AL[14] = [11, 16] 59 | AL[15] = [12, 17, 18] 60 | AL[16] = [14] 61 | AL[17] = [15] 62 | AL[18] = [15] 63 | 64 | par = [-1] * N 65 | heavy = [-1] * N 66 | heavy_light(0) 67 | 68 | group = [-1] * N 69 | decompose(0, 0) 70 | 71 | for i in range(N): 72 | print('%2d, parent = %2d, heaviest child = %2d, belong to heavy-paths group = %d' % (i, par[i], heavy[i], group[i])) 73 | 74 | 75 | main() 76 | -------------------------------------------------------------------------------- /cpbook-code/ch9/LCA.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define MAX_N 1000 5 | 6 | vector> children; 7 | 8 | int L[2*MAX_N], E[2*MAX_N], H[MAX_N], idx; 9 | 10 | void dfs(int cur, int depth) { 11 | H[cur] = idx; 12 | E[idx] = cur; 13 | L[idx++] = depth; 14 | for (auto &nxt : children[cur]) { 15 | dfs(nxt, depth+1); 16 | E[idx] = cur; // backtrack to current node 17 | L[idx++] = depth; 18 | } } 19 | 20 | void buildRMQ() { 21 | idx = 0; 22 | memset(H, -1, sizeof H); 23 | dfs(0, 0); // we assume that the root is at index 0 24 | } 25 | 26 | int main() { 27 | children.assign(10, {}); 28 | children[0] = {1, 7}; 29 | children[1] = {2, 3, 6}; 30 | children[3] = {4, 5}; 31 | children[7] = {8, 9}; 32 | 33 | buildRMQ(); 34 | for (int i = 0; i < 2*10-1; i++) printf("%d ", H[i]); 35 | printf("\n"); 36 | for (int i = 0; i < 2*10-1; i++) printf("%d ", E[i]); 37 | printf("\n"); 38 | for (int i = 0; i < 2*10-1; i++) printf("%d ", L[i]); 39 | printf("\n"); 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /cpbook-code/ch9/LCA.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class LCA { 4 | public static Vector< Vector < Integer > > children = new Vector < Vector < Integer > > (); 5 | public static int[] L = new int[2000], E = new int[2000], H = new int[2000]; 6 | public static int idx; 7 | 8 | public static void dfs(int cur, int depth) { 9 | H[cur] = idx; 10 | E[idx] = cur; 11 | L[idx++] = depth; 12 | for (int i = 0; i < children.get(cur).size(); i++) { 13 | dfs(children.get(cur).get(i), depth+1); 14 | E[idx] = cur; // backtrack to current node 15 | L[idx++] = depth; 16 | } 17 | } 18 | 19 | public static void buildRMQ() { 20 | idx = 0; 21 | for (int i = 0; i < 2000; i++) 22 | H[i] = -1; 23 | dfs(0, 0); // we assume that the root is at index 0 24 | } 25 | 26 | public static void main(String[] args) { 27 | for (int i = 0; i < 10; i++) 28 | children.add(new Vector < Integer > ()); 29 | 30 | children.get(0).add(1); children.get(0).add(7); 31 | children.get(1).add(2); children.get(1).add(3); children.get(1).add(6); 32 | children.get(3).add(4); children.get(3).add(5); 33 | children.get(7).add(8); children.get(7).add(9); 34 | 35 | buildRMQ(); 36 | for (int i = 0; i < 2*10-1; i++) System.out.printf("%d ", H[i]); 37 | System.out.printf("\n"); 38 | for (int i = 0; i < 2*10-1; i++) System.out.printf("%d ", E[i]); 39 | System.out.printf("\n"); 40 | for (int i = 0; i < 2*10-1; i++) System.out.printf("%d ", L[i]); 41 | System.out.printf("\n"); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /cpbook-code/ch9/LCA.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | 3 | let max_n = 1000 4 | 5 | let children = Array.make max_n [] 6 | 7 | let l = Array.make (2*max_n) 0 8 | let e = Array.make (2*max_n) 0 9 | let h = Array.make max_n (-1) 10 | let idx = ref 0 11 | 12 | let rec dfs cur depth = 13 | h.(cur) <- !idx; 14 | e.(!idx) <- cur; 15 | l.(!idx) <- depth; 16 | idx := !idx+1; 17 | children.(cur) |> List.iter (fun nxt -> 18 | dfs nxt (depth+1); 19 | e.(!idx) <- cur; (* backtrack to current node *) 20 | l.(!idx) <- depth; 21 | idx := !idx+1 22 | ) 23 | 24 | let build_rmq () = 25 | dfs 0 0 (* we assume that the root is at index 0 *) 26 | 27 | let () = 28 | children.(0) <- [1; 7]; 29 | children.(1) <- [2; 3; 6]; 30 | children.(3) <- [4; 5]; 31 | children.(7) <- [8; 9]; 32 | 33 | build_rmq (); 34 | for i = 0 to 2*10-2 do 35 | printf "%d " h.(i) 36 | done; 37 | printf "\n"; 38 | for i = 0 to 2*10-2 do 39 | printf "%d " e.(i) 40 | done; 41 | printf "\n"; 42 | for i = 0 to 2*10-2 do 43 | printf "%d " l.(i) 44 | done; 45 | printf "\n"; 46 | -------------------------------------------------------------------------------- /cpbook-code/ch9/LCA.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | MAX_N = 1000 4 | 5 | children = [] 6 | L = [0] * (2*MAX_N) 7 | E = [0] * (2*MAX_N) 8 | H = [0] * (2*MAX_N) 9 | idx = 0 10 | 11 | def dfs(cur, depth): 12 | global children, L, E, H, idx 13 | 14 | H[cur] = idx 15 | E[idx] = cur 16 | L[idx] = depth 17 | idx += 1 18 | for nxt in children[cur]: 19 | dfs(nxt, depth+1) 20 | E[idx] = cur 21 | L[idx] = depth 22 | idx += 1 23 | 24 | def buildRMQ(): 25 | global idx, H, MAX_N 26 | 27 | idx = 0 28 | H = [-1] * (2*MAX_N) 29 | dfs(0, 0) 30 | 31 | 32 | def main(): 33 | global children, H, E, L 34 | 35 | children = [list() for _ in range(10)] 36 | children[0] = [1, 7] 37 | children[1] = [2, 3, 6] 38 | children[3] = [4, 5] 39 | children[7] = [8, 9] 40 | 41 | buildRMQ() 42 | print(' '.join([str(H[i]) for i in range(2*10-1)])) 43 | print(' '.join([str(E[i]) for i in range(2*10-1)])) 44 | print(' '.join([str(L[i]) for i in range(2*10-1)])) 45 | 46 | 47 | main() 48 | -------------------------------------------------------------------------------- /cpbook-code/ch9/SparseTable.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | class SparseTable: 4 | def __init__(self, A=[]): 5 | self.A = A 6 | self.P2 = [] 7 | self.L2 = [] 8 | self.SpT = [] 9 | 10 | n = len(self.A) 11 | L2_n = int(math.log2(n)) + 1 12 | self.P2 = [0] * (L2_n+1) 13 | self.L2 = [0] * (2**L2_n+1) 14 | for i in range(L2_n+1): 15 | self.P2[i] = 2**i 16 | self.L2[2**i] = i 17 | for i in range(2, self.P2[L2_n]): 18 | if self.L2[i] == 0: 19 | self.L2[i] = self.L2[i-1] 20 | 21 | self.SpT = [[None] * n for _ in range(self.L2[n]+1)] 22 | for j in range(n): 23 | self.SpT[0][j] = j 24 | 25 | for i in range(1, L2_n+1): 26 | for j in range(n-self.P2[i]+1): 27 | x = self.SpT[i-1][j] 28 | y = self.SpT[i-1][j+self.P2[i-1]] 29 | self.SpT[i][j] = x if A[x] <= A[y] else y 30 | 31 | def RMQ(self, i, j): 32 | k = self.L2[j-i+1] 33 | x = self.SpT[k][i] 34 | y = self.SpT[k][j-self.P2[k]+1] 35 | return x if self.A[x] <= self.A[y] else y 36 | 37 | 38 | def main(): 39 | A = [18, 17, 13, 19, 15, 11, 20] 40 | SpT = SparseTable(A) 41 | n = len(A) 42 | for i in range(n): 43 | for j in range(i, n): 44 | print('RMQ(%d, %d) = %d' % (i, j, SpT.RMQ(i,j))) 45 | 46 | 47 | main() 48 | -------------------------------------------------------------------------------- /cpbook-code/ch9/heliocentric.ml: -------------------------------------------------------------------------------- 1 | open Scanf 2 | open Printf 3 | 4 | let modu a m = 5 | (a mod m + m) mod m 6 | 7 | let extEuclid a b = 8 | let rec go a b x xx y yy = 9 | if b = 0 then 10 | a, x, y 11 | else 12 | let q = a / b in 13 | go b (a mod b) xx (x - q * xx) yy (y - q * yy) 14 | in 15 | go a b 1 0 0 1 16 | 17 | let modInverse b m = 18 | let d, x, y = extEuclid b m in 19 | if d <> 1 then -1 20 | else modu x m 21 | 22 | let crt rs ms = 23 | let mt = List.fold_left ( * ) 1 ms in 24 | List.map2 25 | (fun r m -> 26 | let a = modu (r * modInverse (mt / m) m) m in 27 | modu (a * (mt / m)) mt 28 | ) 29 | rs ms 30 | |> List.fold_left (fun x y -> modu (x + y) mt) 0 31 | 32 | let main = 33 | try 34 | let caseNo = ref 0 in 35 | while true do 36 | let e, m = scanf "%d %d\n" (fun e m -> e, m) in 37 | let orbit = [365; 687] in 38 | let rs = [365 - e; 687 - m] in 39 | let ans = crt rs orbit in 40 | incr caseNo; 41 | printf "Case %d: %d\n" !caseNo ans; 42 | done 43 | with End_of_file -> 44 | () 45 | -------------------------------------------------------------------------------- /cpbook-code/ch9/heliocentric.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | def extEuclid(aa, bb): 4 | lastremainder, remainder = abs(aa), abs(bb) 5 | x, lastx, y, lasty = 0, 1, 1, 0 6 | while remainder: 7 | lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder) 8 | x, lastx = lastx - quotient*x, x 9 | y, lasty = lasty - quotient*y, y 10 | return lastremainder, lastx * (-1 if aa < 0 else 1), lasty * (-1 if bb < 0 else 1) 11 | 12 | def modinv(b, m): 13 | d, x, y = extEuclid(b,m) 14 | if d != 1: 15 | raise ValueError 16 | return x % m 17 | 18 | def crt(r, m): 19 | n = len(m) 20 | mt = 1 21 | for i in range(n): 22 | mt *= m[i] 23 | sm = 0 24 | for i in range(n): 25 | p = mt//m[i] 26 | sm += r[i] * modinv(p, m[i]) * p 27 | return sm % mt 28 | 29 | caseNo = 0 30 | for line in sys.stdin: 31 | e, m = map(int,line.split()) 32 | ans = crt([365-e, 687-m], [365, 687]) 33 | caseNo += 1 34 | print("Case %d: %d" % (caseNo, ans)) 35 | -------------------------------------------------------------------------------- /cpbook-code/ch9/mcmf_in.txt: -------------------------------------------------------------------------------- 1 | 8 11 0 7 2 | 0 1 10 1 3 | 0 2 15 2 4 | 1 3 10 0 5 | 2 3 5 1 6 | 3 4 10 4 7 | 1 5 10 6 8 | 2 6 10 5 9 | 4 5 20 2 10 | 4 6 15 7 11 | 5 7 10 8 12 | 6 7 15 9 13 | --------------------------------------------------------------------------------