├── Round E ├── Street Checkers │ ├── input.txt │ ├── solution.cpp │ ├── README.md │ └── analysis.md ├── Cherries Mesh │ ├── input.txt │ ├── solution.cpp │ ├── analysis.md │ └── README.md ├── Code-Eat Switcher │ ├── input.txt │ ├── analysis.md │ └── solution.js └── README.md ├── Round H ├── H-index │ ├── input.txt │ ├── solution.cpp │ ├── analysis.md │ ├── solution.js │ └── README.md ├── Diagonal Puzzle │ ├── input.txt │ ├── solution.js │ ├── analysis.md │ └── README.md ├── Elevanagram │ ├── input.txt │ ├── solution.js │ ├── README.md │ └── analysis.md └── README.md ├── Round G ├── Shifts │ ├── input.txt │ ├── analysis.md │ ├── README.md │ └── solution.js ├── The Equation │ ├── input.txt │ ├── solution.js │ ├── analysis.md │ └── README.md ├── Book Reading │ ├── input.txt │ ├── solution.cpp │ ├── analysis.md │ └── README.md └── README.md ├── Practice Round ├── Mural │ ├── input.txt │ ├── solution.js │ ├── analysis.md │ └── README.md ├── Kickstart Alarm │ ├── input.txt │ ├── solution.cpp │ ├── solution.js │ └── analysis.md ├── README.md └── Number Guessing │ ├── solution.c │ └── solution.js ├── Round A ├── Training │ ├── input.txt │ ├── solution.js │ ├── analysis.md │ └── README.md ├── Parcels │ ├── input.txt │ └── README.md ├── Contention │ ├── input.txt │ ├── solution_try_2.js │ ├── solution_try_1.js │ ├── analysis.md │ ├── solution_small_test_set.cpp │ └── README.md └── README.md ├── Round C ├── Wiggle Walk │ ├── input.txt │ ├── analysis.md │ └── README.md ├── Catch Some │ ├── input.txt │ ├── analysis.md │ ├── solution.cpp │ └── README.md ├── Circuit Board │ ├── input.txt │ ├── input2.txt │ ├── solution.cpp │ ├── README.md │ └── analysis.md └── README.md ├── Round D ├── X or What? │ ├── input.txt │ ├── solution.cpp │ ├── analysis.md │ └── README.md ├── Latest Guests │ ├── input.txt │ └── analysis.md ├── Food Stalls │ ├── input.txt │ ├── analysis.md │ ├── solution.cpp │ └── README.md └── README.md ├── images ├── round-c-wiggle-walk.png └── round-c-circuit-board.png ├── Round F ├── Teach Me │ ├── input.txt │ ├── solution.js │ ├── analysis.md │ └── README.md ├── Flattening │ ├── input.txt │ ├── solution.js │ ├── analysis.md │ └── README.md ├── README.md └── Spectating Villages │ ├── input.txt │ ├── analysis.md │ ├── solution.js │ └── solution.cpp ├── Round B ├── Building Palindromes │ ├── input.txt │ ├── solution2.js │ ├── solution.js │ ├── analysis.md │ └── README.md ├── Energy Stones │ ├── input.txt │ ├── solution.js │ ├── analysis.md │ └── README.md ├── Diverse Subarray │ ├── input.txt │ ├── analysis.md │ └── README.md └── README.md ├── README.md └── .gitignore /Round E/Street Checkers/input.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 5 10 3 | 102 102 -------------------------------------------------------------------------------- /Round E/Cherries Mesh/input.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 2 1 3 | 1 2 4 | 3 1 5 | 2 3 -------------------------------------------------------------------------------- /Round H/H-index/input.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 3 3 | 5 1 2 4 | 6 5 | 1 3 3 2 2 15 -------------------------------------------------------------------------------- /Round G/Shifts/input.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 2 3 3 | 1 2 4 | 3 3 5 | 2 5 6 | 2 2 7 | 10 30 -------------------------------------------------------------------------------- /Practice Round/Mural/input.txt: -------------------------------------------------------------------------------- 1 | 4 2 | 4 3 | 1332 4 | 4 5 | 9583 6 | 3 7 | 616 8 | 10 9 | 1029384756 -------------------------------------------------------------------------------- /Round A/Training/input.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 4 3 3 | 3 1 9 100 4 | 6 2 5 | 5 5 1 2 3 4 6 | 5 5 7 | 7 7 1 7 7 -------------------------------------------------------------------------------- /Round C/Wiggle Walk/input.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 5 3 6 2 3 3 | EEWNS 4 | 4 3 3 1 1 5 | SESE 6 | 11 5 8 3 4 7 | NEESSWWNESE -------------------------------------------------------------------------------- /Round D/X or What?/input.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 4 3 3 | 10 21 3 7 4 | 1 13 5 | 0 32 6 | 2 22 7 | 5 1 8 | 14 1 15 20 26 9 | 4 26 -------------------------------------------------------------------------------- /Round G/The Equation/input.txt: -------------------------------------------------------------------------------- 1 | 4 2 | 3 27 3 | 8 2 4 4 | 4 45 5 | 30 0 4 11 6 | 1 0 7 | 100 8 | 6 2 9 | 5 5 1 5 1 0 -------------------------------------------------------------------------------- /Practice Round/Kickstart Alarm/input.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 2 3 1 2 1 2 1 1 9 3 | 10 10 10001 10002 10003 10004 10005 10006 89273 -------------------------------------------------------------------------------- /images/round-c-wiggle-walk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wachino/google-kick-start-2019/HEAD/images/round-c-wiggle-walk.png -------------------------------------------------------------------------------- /images/round-c-circuit-board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wachino/google-kick-start-2019/HEAD/images/round-c-circuit-board.png -------------------------------------------------------------------------------- /Round E/Code-Eat Switcher/input.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 4 2 3 | 3 8 4 | 6 10 5 | 0 18 6 | 3 13 7 | 10 0 8 | 7 3 9 | 1 2 10 | 4 4 11 | 4 4 12 | 0 0 -------------------------------------------------------------------------------- /Round A/Parcels/input.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 3 3 3 | 101 4 | 000 5 | 101 6 | 1 2 7 | 11 8 | 5 5 9 | 10001 10 | 00000 11 | 00000 12 | 00000 13 | 10001 -------------------------------------------------------------------------------- /Round C/Catch Some/input.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 4 3 3 | 1 2 4 9 4 | 3 3 2 3 5 | 4 3 6 | 1 2 3 4 7 | 1 8 1 8 8 | 6 6 9 | 4 3 3 1 3 10000 10 | 1 2 8 9 5 7 -------------------------------------------------------------------------------- /Round A/Contention/input.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 5 3 3 | 1 2 4 | 3 4 5 | 2 5 6 | 30 3 7 | 10 11 8 | 10 10 9 | 11 11 10 | 10 4 11 | 1 8 12 | 4 5 13 | 3 6 14 | 2 7 -------------------------------------------------------------------------------- /Round H/Diagonal Puzzle/input.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 3 3 | ..# 4 | #.# 5 | #.. 6 | 5 7 | .#### 8 | #.### 9 | ##.## 10 | ###.# 11 | ##### 12 | 2 13 | ## 14 | ## -------------------------------------------------------------------------------- /Round C/Circuit Board/input.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 1 4 0 3 | 3 1 3 3 4 | 2 3 0 5 | 4 4 5 6 | 7 6 6 7 | 4 5 0 8 | 2 2 4 4 20 9 | 8 3 3 3 12 10 | 6 6 3 3 3 11 | 1 6 8 6 4 -------------------------------------------------------------------------------- /Round F/Teach Me/input.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 4 100 3 | 4 80 90 100 5 4 | 1 90 5 | 1 80 6 | 3 80 90 100 7 | 3 30 8 | 4 10 11 12 13 9 | 4 10 11 12 13 10 | 5 25 26 27 28 29 -------------------------------------------------------------------------------- /Round B/Building Palindromes/input.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 7 5 3 | ABAACCA 4 | 3 6 5 | 4 4 6 | 2 5 7 | 6 7 8 | 3 7 9 | 3 5 10 | XYZ 11 | 1 3 12 | 1 3 13 | 1 3 14 | 1 3 15 | 1 3 -------------------------------------------------------------------------------- /Round H/Elevanagram/input.txt: -------------------------------------------------------------------------------- 1 | 6 2 | 0 0 2 0 0 1 0 0 0 3 | 0 0 0 0 0 0 0 0 12 4 | 0 0 0 0 2 0 1 1 0 5 | 3 1 1 1 0 0 0 0 0 6 | 3 0 0 0 0 0 3 0 2 7 | 0 0 0 0 0 0 0 1 0 8 | ## -------------------------------------------------------------------------------- /Round D/Latest Guests/input.txt: -------------------------------------------------------------------------------- 1 | 4 2 | 5 3 2 3 | 5 C 4 | 2 A 5 | 1 A 6 | 2 4 0 7 | 1 A 8 | 1 C 9 | 1 A 10 | 1 C 11 | 3 2 10 12 | 3 C 13 | 2 A 14 | 6 1 6 15 | 4 A -------------------------------------------------------------------------------- /Round G/Book Reading/input.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 11 1 2 3 | 8 4 | 2 3 5 | 11 11 11 6 | 1 2 3 4 5 6 7 8 9 10 11 7 | 1 2 3 4 5 6 7 8 9 10 11 8 | 1000 6 1 9 | 4 8 15 16 23 42 10 | 1 -------------------------------------------------------------------------------- /Round B/Energy Stones/input.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 4 3 | 20 10 1 4 | 5 30 5 5 | 100 30 1 6 | 5 80 60 7 | 3 8 | 10 4 1000 9 | 10 3 1000 10 | 10 8 1000 11 | 2 12 | 12 300 50 13 | 5 200 0 -------------------------------------------------------------------------------- /Round C/Circuit Board/input2.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 1 4 2 3 | 3 1 3 3 4 | 3 3 2 5 | 0 5 0 6 | 8 12 3 7 | 7 10 1 8 | 4 4 8 9 | 20 10 20 10 10 | 10 4 5 20 11 | 20 5 4 10 12 | 10 20 10 20 -------------------------------------------------------------------------------- /Round F/Flattening/input.txt: -------------------------------------------------------------------------------- 1 | 4 2 | 8 2 3 | 300 100 300 300 200 100 800 500 4 | 5 3 5 | 100 100 100 100 3 6 | 7 3 7 | 10 20 40 10 10 30 30 8 | 10 2 9 | 30 30 60 60 90 90 60 60 30 30 -------------------------------------------------------------------------------- /Round D/Food Stalls/input.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 2 4 3 | 1 2 3 10 4 | 100 70 80 20 5 | 1 5 6 | 150 300 301 400 700 7 | 8 35 26 5 2 8 | 6 7 9 | 22 21 20 23 26 25 24 10 | 10 10 10 10 10 10 10 -------------------------------------------------------------------------------- /Round G/README.md: -------------------------------------------------------------------------------- 1 | # Round G 2 | 3 | ## Problems 4 | 5 | - [Book Reading](/Round%20G/Book%20Reading) 6 | - [The Equation](/Round%20G/The%20Equation) 7 | - [Shifts](/Round%20G/Shifts) 8 | -------------------------------------------------------------------------------- /Round B/Diverse Subarray/input.txt: -------------------------------------------------------------------------------- 1 | 4 2 | 6 2 3 | 1 1 4 1 4 4 4 | 8 1 5 | 1 2 500 3 4 500 6 7 6 | 10 1 7 | 100 200 8 8 8 8 8 300 400 100 8 | 12 2 9 | 40 50 1 1 1 60 70 2 2 2 80 90 10 | -------------------------------------------------------------------------------- /Round H/README.md: -------------------------------------------------------------------------------- 1 | # Round H 2 | 3 | ## Problems 4 | 5 | - [H-index](/Round%20H/H-index) 6 | - [Diagonal Puzzle](/Round%20H/Diagonal%20Puzzle) 7 | - [Elevanagram](/Round%20H/Elevanagram) 8 | -------------------------------------------------------------------------------- /Round D/README.md: -------------------------------------------------------------------------------- 1 | # Round D 2 | 3 | ## Problems 4 | 5 | - [X or What?](/Round%20D/X%20or%20What%3F) 6 | - [Latest Guests](/Round%20D/Latest%20Guests) 7 | - [Food Stalls](/Round%20D/Food%20Stalls) 8 | -------------------------------------------------------------------------------- /Round F/README.md: -------------------------------------------------------------------------------- 1 | # Round F 2 | 3 | ## Problems 4 | 5 | - [Flattening](/Round%20F/Flattening) 6 | - [Teach Me](/Round%20F/Teach%20Me) 7 | - [Spectating Villages](/Round%20F/Spectating%20Villages) 8 | -------------------------------------------------------------------------------- /Round F/Spectating Villages/input.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 9 3 | -10 4 -10 8 20 30 -2 -3 7 4 | 1 4 5 | 2 4 6 | 4 3 7 | 9 4 8 | 9 8 9 | 7 5 10 | 6 7 11 | 7 9 12 | 4 13 | -2 20 20 20 14 | 1 2 15 | 1 3 16 | 1 4 17 | 5 18 | -5 -10 8 -7 -2 19 | 5 4 20 | 4 3 21 | 3 2 22 | 2 1 23 | -------------------------------------------------------------------------------- /Round A/README.md: -------------------------------------------------------------------------------- 1 | # Round A 2 | 3 | ## Problems 4 | 5 | - [Training](/Round%20A/Training) 6 | - [Parcels](/Round%20A/Parcels) 7 | - [Contention](/Round%20A/Contention) 8 | 9 | ## Contest results 10 | 11 | - [Link to my submissions](https://codingcompetitions.withgoogle.com/kickstart/submissions/0000000000050e01/d2FjaGlubw) 12 | - Ranking position: 2802 13 | -------------------------------------------------------------------------------- /Round C/README.md: -------------------------------------------------------------------------------- 1 | # Round C 2 | 3 | ## Problems 4 | 5 | - [Wiggle Walk](/Round%20C/Wiggle%20Walk) 6 | - [Circuit Board](/Round%20C/Circuit%20Board) 7 | - [Catch Some](/Round%20C/Catch%20Some) 8 | 9 | ## Contest results 10 | 11 | - [Link to my submissions](https://codingcompetitions.withgoogle.com/kickstart/submissions/0000000000050ff2/d2FjaGlubw) 12 | - Ranking position: 471 13 | -------------------------------------------------------------------------------- /Round E/README.md: -------------------------------------------------------------------------------- 1 | # Round E 2 | 3 | ## Problems 4 | 5 | - [Cherries Mesh](/Round%20E/Cherries%20Mesh) 6 | - [Code-Eat Switcher](/Round%20E/Code-Eat%20Switcher) 7 | - [Street Checkers](/Round%20E/Street%20Checkers) 8 | 9 | ## Contest results 10 | 11 | - [Link to my submissions](https://codingcompetitions.withgoogle.com/kickstart/submissions/0000000000050edb/d2FjaGlubw) 12 | - Ranking position: 796 13 | -------------------------------------------------------------------------------- /Round B/README.md: -------------------------------------------------------------------------------- 1 | # Round B 2 | 3 | ## Problems 4 | 5 | - [Building Palindromes](/Round%20B/Building%20Palindromes) 6 | - [Energy Stones](/Round%20B/Energy%20Stones) 7 | - [Diverse Subarray](/Round%20B/Diverse%20Subarray) 8 | 9 | ## Contest results 10 | 11 | - [Link to my submissions](https://codingcompetitions.withgoogle.com/kickstart/submissions/0000000000050eda/d2FjaGlubw) 12 | - Ranking position: 471 13 | -------------------------------------------------------------------------------- /Practice Round/README.md: -------------------------------------------------------------------------------- 1 | # Practice Round 2 | 3 | ## Problems 4 | 5 | - [Number Guessing](/Practice%20Round/Number%20Guessing) 6 | - [Mural](/Practice%20Round/Mural) 7 | - [Kickstart Alarm](/Practice%20Round/Kickstart%20Alarm) 8 | 9 | ## Contest results 10 | 11 | - [Link to my submissions](https://codingcompetitions.withgoogle.com/kickstart/submissions/0000000000051060/d2FjaGlubw) 12 | - Ranking position: 1314 13 | -------------------------------------------------------------------------------- /Practice Round/Number Guessing/solution.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() 4 | { 5 | int T; 6 | scanf("%d", &T); 7 | int i = 0; 8 | int j = 0; 9 | int A, B, N; 10 | char res[20]; 11 | 12 | for (i = 0; i < T; i++) { 13 | scanf("%d %d", &A, &B); 14 | scanf("%d", &N); 15 | for (j = 0; j < N; j++) { 16 | printf("%d\n",(A+B+1)/2); 17 | fflush(stdout); 18 | scanf("%s", res); 19 | if (strcmp("CORRECT",res) == 0) { 20 | break; 21 | } else if (strcmp("TOO_SMALL", res) == 0) { 22 | A = (A+B+1)/2; 23 | } else if (strcmp("TOO_BIG", res) == 0) { 24 | B = (A+B+1)/2 - 1; 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kick Start 2019 2 | 3 | This project contains my solutions for [Kick Start 2019 competition 2019](https://codingcompetitions.withgoogle.com/kickstart/archive/2019) 4 | 5 | ## Practice Round 6 | 7 | - [Problem statements and solutions](/Practice%20Round) 8 | 9 | ## Round A 10 | 11 | - [Problem statements and solutions](/Round%20A) 12 | 13 | ## Round B 14 | 15 | - [Problem statements and solutions](/Round%20B) 16 | 17 | ## Round C 18 | 19 | - [Problem statements and solutions](/Round%20C) 20 | 21 | ## Round D 22 | 23 | - [Problem statements and solutions](/Round%20D) 24 | 25 | ## Round E 26 | 27 | - [Problem statements and solutions](/Round%20E) 28 | 29 | ## Round F 30 | 31 | - [Problem statements and solutions](/Round%20F) 32 | 33 | ## Round G 34 | 35 | - [Problem statements and solutions](/Round%20G) 36 | 37 | ## Round H 38 | 39 | - [Problem statements and solutions](/Round%20H) 40 | -------------------------------------------------------------------------------- /Round H/H-index/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | int main() 12 | { 13 | int T, N; 14 | int citation; 15 | priority_queue, greater> heap; 16 | 17 | cin >> T; 18 | for (int t = 0; t < T; t++) 19 | { 20 | cin >> N; 21 | heap = priority_queue, greater>(); 22 | cout << "Case #" << t + 1 << ":"; 23 | 24 | int hIndex = 0; 25 | for (int i = 0; i < N; i++) 26 | { 27 | cin >> citation; 28 | heap.push(citation); 29 | while (!heap.empty() && heap.top() <= hIndex) 30 | { 31 | heap.pop(); 32 | } 33 | if (heap.size() > hIndex) 34 | { 35 | hIndex++; 36 | } 37 | cout << " " << hIndex; 38 | } 39 | cout << endl; 40 | } 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /Round G/Book Reading/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | int main() 11 | { 12 | int T; 13 | int N, M, Q, to; 14 | long long sum, x; 15 | bool tornOut[100001]; 16 | long long readers[100001]; 17 | 18 | cin >> T; 19 | 20 | for (int t = 0; t < T; t++) 21 | { 22 | cin >> N >> M >> Q; 23 | sum = 0L; 24 | 25 | for (int i = 0; i <= N; i++) 26 | { 27 | tornOut[i] = false; 28 | readers[i] = 0; 29 | } 30 | for (int i = 0; i < M; i++) 31 | { 32 | 33 | cin >> to; 34 | tornOut[to] = true; 35 | } 36 | 37 | for (int i = 1; i <= N; i++) 38 | { 39 | for (long long j = 1; j * i <= N; j++) 40 | { 41 | if (!tornOut[j * i]) 42 | { 43 | readers[i]++; 44 | } 45 | } 46 | } 47 | for (int i = 0; i < Q; i++) 48 | { 49 | cin >> x; 50 | sum += readers[x]; 51 | } 52 | 53 | cout << "Case #" << t + 1 << ": " << sum << endl; 54 | } 55 | 56 | return 0; 57 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | .vscode/ 64 | -------------------------------------------------------------------------------- /Practice Round/Mural/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', inputStdin => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', _ => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map(str => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | function solution() { 24 | const t = Number(readLine()); 25 | for (let i = 0; i < t; i++) { 26 | const n = Number(readLine()); 27 | const beautyScores = readLine() 28 | .split('') 29 | .map(Number); 30 | const muralLength = Math.ceil(n / 2); 31 | let maxBeauty = beautyScores.slice(0, muralLength).reduce((a, b) => a + b); 32 | let currBeauty = maxBeauty; 33 | 34 | for (let j = muralLength; j < beautyScores.length; j++) { 35 | currBeauty += beautyScores[j]; 36 | currBeauty -= beautyScores[j - muralLength]; 37 | if (currBeauty > maxBeauty) { 38 | maxBeauty = currBeauty; 39 | } 40 | } 41 | console.log(`Case #${i + 1}: ${maxBeauty}`); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Practice Round/Number Guessing/solution.js: -------------------------------------------------------------------------------- 1 | const rl = require('readline'); 2 | 3 | const rli = rl.createInterface({ 4 | input: process.stdin, 5 | output: process.stdout, 6 | crlfDelay: Infinity 7 | }); 8 | 9 | async function* getLineGenerator() { 10 | for await (const line of rli) { 11 | yield line; 12 | } 13 | } 14 | const lineGenerator = getLineGenerator(); 15 | 16 | async function readLine() { 17 | const line = await lineGenerator.next(); 18 | return line.value; 19 | } 20 | 21 | async function solve() { 22 | let res = ''; 23 | const t = Number(await readLine()); 24 | for (let i = 0; i < t; i++) { 25 | let [a, b] = (await readLine()) 26 | .trim() 27 | .split(' ') 28 | .map(Number); 29 | let n = Number(await readLine()); 30 | for (let j = 0; j < n; j++) { 31 | console.log(Math.floor((a + b + 1) / 2)); 32 | 33 | res = await readLine(); 34 | if ('CORRECT' === res) { 35 | break; 36 | } else if ('TOO_SMALL' === res) { 37 | a = (a + b + 1) / 2; 38 | } else if ('TOO_BIG' === res) { 39 | b = (a + b + 1) / 2 - 1; 40 | } 41 | } 42 | } 43 | rli.close(); 44 | process.stdin.destroy(); 45 | } 46 | 47 | solve(); 48 | -------------------------------------------------------------------------------- /Round E/Street Checkers/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | bool isInteresting(int x) 11 | { 12 | int a = x; 13 | int p = 0; 14 | int k = 0; 15 | while (a % 2 == 0) 16 | { 17 | p++; 18 | a /= 2; 19 | } 20 | if (p == 1) 21 | { 22 | return true; 23 | } 24 | if (p > 3) 25 | { 26 | return false; 27 | } 28 | for (int i = 1; i * i <= a; i++) 29 | { 30 | if (a % i == 0) 31 | { 32 | k++; 33 | if (i * i < a) 34 | { 35 | k++; 36 | } 37 | if ((p == 0 || p == 2) && k > 2) 38 | { 39 | return false; 40 | } 41 | else if (p == 3 && k > 1) 42 | { 43 | return false; 44 | } 45 | } 46 | } 47 | 48 | return abs(k * (p - 1)) <= 2; 49 | } 50 | 51 | int main() 52 | { 53 | int T; 54 | int L, R; 55 | int sum; 56 | 57 | cin >> T; 58 | 59 | for (int t = 0; t < T; t++) 60 | { 61 | cin >> L >> R; 62 | sum = 0; 63 | for (int i = L; i <= R; i++) 64 | { 65 | if (isInteresting(i)) 66 | { 67 | sum++; 68 | } 69 | } 70 | 71 | cout << "Case #" << t + 1 << ": " << sum << endl; 72 | } 73 | 74 | return 0; 75 | } -------------------------------------------------------------------------------- /Round E/Cherries Mesh/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | int subconjuntos[100001]; 12 | 13 | int find(int subsets[], int i) 14 | { 15 | if (subsets[i] != i) 16 | subsets[i] = find(subsets, subsets[i]); 17 | 18 | return subsets[i]; 19 | } 20 | 21 | void setUnion(int subsets[], int x, int y) 22 | { 23 | int xroot = find(subsets, x); 24 | int yroot = find(subsets, y); 25 | subsets[xroot] = yroot; 26 | } 27 | 28 | int main() 29 | { 30 | int T, M, N; 31 | int c, d, black; 32 | 33 | cin >> T; 34 | 35 | for (int t = 0; t < T; t++) 36 | { 37 | cin >> N >> M; 38 | black = M; 39 | 40 | for (int v = 0; v < N; v++) 41 | { 42 | subconjuntos[v] = v; 43 | } 44 | 45 | for (int i = 0; i < M; i++) 46 | { 47 | cin >> c >> d; 48 | c--; 49 | d--; 50 | int x = find(subconjuntos, c); 51 | int y = find(subconjuntos, d); 52 | 53 | if (x == y) 54 | { 55 | black--; 56 | } 57 | else 58 | { 59 | setUnion(subconjuntos, x, y); 60 | } 61 | } 62 | 63 | cout << "Case #" << t + 1 << ": " << 2 * (N - 1) - black << endl; 64 | } 65 | 66 | return 0; 67 | } -------------------------------------------------------------------------------- /Round G/Book Reading/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 4 | 5 | We can solve this test set by naively computing the number of pages that each lazy readers will read. We can do this by initially having an array torn of **N** booleans, where torn[x] is true if and only if page x is torn out, and then for each lazy reader i, we can iterate from 1 to **N**, incrementing our answer only if the value that we iterate is a multiple of **Ri** and not torn out. 6 | 7 | The running time of this solution is O(**N** × **Q**). 8 | 9 | ## Test set 2 10 | 11 | Let f(x) be the number of pages that are multiples of x and not torn out. To compute f(x), we can only check whether the pages x, 2x, 3x, ..., floor(**N**/x)x are torn out. Therefore, we can do this in **N**/x time. 12 | 13 | This means that we can compute f(1), f(2), ..., f(**N**) in a total of **N**(1/1 + 1/2 + ... + 1/**N**) time. 1/1 + 1/2 + ... + 1/**N** is approximately O(log **N**) (since the n-th [harmonic number](https://en.wikipedia.org/wiki/Harmonic_number) is approximately O(log **N**)), so in total f(1), f(2), ..., f(**N**) can be computed in a total of O(**N** log **N**) time. 14 | 15 | After precomputing f(x), we can easily count the number of pages that each lazy readers will read in O(1). The running time of this solution is O(**N** log **N** + **Q**). 16 | -------------------------------------------------------------------------------- /Round A/Training/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', inputStdin => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', _ => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map(str => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | function solution() { 24 | const t = Number(readLine()); 25 | for (let i = 0; i < t; i++) { 26 | let [n, p] = readLine() 27 | .split(' ') 28 | .map(Number); 29 | let skills = readLine() 30 | .split(' ') 31 | .map(Number); 32 | skills.sort((a, b) => a - b); 33 | let minTrainingHours = Number.POSITIVE_INFINITY; 34 | let sums = Array(skills).fill(0); 35 | let tmpSum = 0; 36 | for (let j = 0; j < skills.length; j++) { 37 | tmpSum += skills[j]; 38 | sums[j] = tmpSum; 39 | } 40 | 41 | for (let j = p - 1; j < n; j++) { 42 | let candidate = skills[j] * p - (sums[j] - (j > p - 1 ? sums[j - p] : 0)); 43 | if (candidate < minTrainingHours) { 44 | minTrainingHours = candidate; 45 | } 46 | } 47 | 48 | console.log(`Case #${i + 1}: ${minTrainingHours}`); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Round B/Building Palindromes/solution2.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', inputStdin => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', _ => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map(str => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | function solution() { 24 | const t = Number(readLine()); 25 | for (let i = 0; i < t; i++) { 26 | let [n, q] = readLine() 27 | .split(' ') 28 | .map(Number); 29 | var blocks = readLine().split(''); 30 | let solution = 0; 31 | 32 | for (let j = 0; j < q; j++) { 33 | let [l, r] = readLine() 34 | .split(' ') 35 | .map(Number); 36 | if (check(l - 1, r)) { 37 | solution++; 38 | } 39 | } 40 | 41 | console.log(`Case #${i + 1}: ${solution}`); 42 | } 43 | 44 | function check(l, r) { 45 | const dicc = {}; 46 | for (let i = l; i < r; i++) { 47 | let char = blocks[i]; 48 | if (!dicc[char]) { 49 | dicc[char] = 0; 50 | } 51 | dicc[char]++; 52 | } 53 | 54 | return Object.values(dicc).reduce((a, b) => a + (b % 2), 0) <= 1; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Practice Round/Kickstart Alarm/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int mod = 1000000007; 6 | 7 | long long power(long long x, long long y) 8 | { 9 | long long t = 1; 10 | while (y != 0) 11 | { 12 | if (y % 2 == 1) 13 | { 14 | t = (t * x) % mod; 15 | } 16 | x = (x * x) % mod; 17 | y /= 2; 18 | } 19 | return t; 20 | } 21 | 22 | int main() 23 | { 24 | int T; 25 | long long int N, K, x1, y1, C, D, E1, E2, F; 26 | cin >> T; 27 | for (int t = 0; t < T; t++) 28 | { 29 | cin >> N >> K >> x1 >> y1 >> C >> D >> E1 >> E2 >> F; 30 | long long *a = new long long int[N + 1]; 31 | a[1] = (x1 + y1) % F; 32 | long long int x, y; 33 | 34 | for (int i = 2; i <= N; i++) 35 | { 36 | x = (C * x1 + D * y1 + E1) % F; 37 | y = (D * x1 + C * y1 + E2) % F; 38 | a[i] = (x + y) % F; 39 | x1 = x; 40 | y1 = y; 41 | } 42 | 43 | long long ans = 0; 44 | long long la = K; 45 | long long xx; 46 | for (long long int i = 2; i <= N + 1; i++) 47 | { 48 | ans = (ans + ((((la * (N + 2 - i)) % mod) * (a[i - 1])) % mod)) % mod; 49 | xx = ((power((i), K + 1) - 1) * power((i - 1), mod - 2)) % mod; 50 | xx--; 51 | if (xx < 0) 52 | { 53 | xx += mod; 54 | } 55 | la += xx; 56 | la %= mod; 57 | } 58 | cout << "Case #" << t + 1 << ": " << ans << endl; 59 | } 60 | 61 | return 0; 62 | } -------------------------------------------------------------------------------- /Round G/The Equation/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', (inputStdin) => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', (_) => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map((str) => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | function solution() { 24 | const T = Number(readLine()); 25 | for (let t = 0; t < T; t++) { 26 | let [N, M] = readLine().split(/\s+/).map(BigInt); 27 | let laws = readLine().split(/\s+/).map(BigInt); 28 | let bits = Array(51).fill(0n); 29 | let sum = laws.reduce((a, b) => a + b); 30 | let k = 0n; 31 | for (let p = 0n; p <= 50n; p++) { 32 | let c = 0n; 33 | for (let i = 0n; i < N; i++) { 34 | if ((laws[i] & (1n << p)) === 0n) { 35 | c++; 36 | } 37 | } 38 | if (c <= N / 2n) { 39 | k |= 1n << p; 40 | sum -= (N - 2n * c) << p; 41 | } 42 | bits[p] = c; 43 | } 44 | 45 | for (let p = 50n; p >= 0n; p--) { 46 | if ((k & (1n << p)) === 0n && sum + ((2n * bits[p] - N) << p) <= M) { 47 | k |= 1n << p; 48 | sum += (2n * bits[p] - N) << p; 49 | } 50 | } 51 | 52 | console.log(`Case #${t + 1}: ${sum <= M ? k : -1}`); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Round F/Teach Me/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', (inputStdin) => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', (_) => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map((str) => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | function solution() { 24 | const T = Number(readLine()); 25 | for (let t = 0; t < T; t++) { 26 | let [N, S] = readLine().split(' ').map(Number); 27 | let skills = []; 28 | let skillCount = {}; 29 | for (let i = 0; i < N; i++) { 30 | let s = readLine() 31 | .split(' ') 32 | .slice(1) 33 | .map(Number) 34 | .sort((a, b) => a - b); 35 | skills.push(s); 36 | s = s.join(','); 37 | skillCount[s] = -~skillCount[s]; 38 | } 39 | let sum = 0; 40 | for (let i = 0; i < N; i++) { 41 | for (let subset of subsets(skills[i])) { 42 | sum += skillCount[subset.sort((a, b) => a - b).join(',')] || 0; 43 | } 44 | } 45 | console.log(`Case #${t + 1}: ${N * N - sum}`); 46 | } 47 | } 48 | 49 | function* subsets(array, offset = 0) { 50 | while (offset < array.length) { 51 | let first = array[offset++]; 52 | for (let subset of subsets(array, offset)) { 53 | subset.push(first); 54 | yield subset; 55 | } 56 | } 57 | yield []; 58 | } 59 | -------------------------------------------------------------------------------- /Round E/Cherries Mesh/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | First, let's rephrase the problem: Given a [complete](https://en.wikipedia.org/wiki/Complete_graph) undirected graph, where each edge has weight 1 or 2, what is the cost of the [Minimum Spanning Tree](https://en.wikipedia.org/wiki/Minimum_spanning_tree)? There are a few different algorithms for solving this problem, such as [Prim's Algorithm](https://en.wikipedia.org/wiki/Prim%27s_algorithm) and [Kruskal's algorithm](https://en.wikipedia.org/wiki/Kruskal%27s_algorithm). Using either of these algorithms gives an O(**N2** log **N**) solution per test case (or O(**N2**) if you use the fact that each edge weight is either 1 or 2). 6 | 7 | ## Test set 2 (Hidden) 8 | 9 | Intuitively, we want to include as many edges of weight 1 as possible. Once we've included as many such edges as we can, then we know that the rest of the edges in the spanning tree will be weight 2. 10 | 11 | Using this idea, we have the following solution: first create a [spanning forest](https://en.wikipedia.org/wiki/Spanning_tree#Spanning_forests) using only edges of weight 1. We can now connect each of the components of the spanning forest together using X-1 edges of weight 2, where X is the number of components (this is possible since the graph is complete). 12 | 13 | Since we only need to print the minimum cost and not the actual minimum spanning tree, we can simplify the problem to simply counting the number of components in the graph where we only consider the edges of weight 1. 14 | 15 | This solves the problem in O(**N**). 16 | -------------------------------------------------------------------------------- /Round E/Code-Eat Switcher/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | Let's start with the brute force way of solving the problem. We can iterate through all possible coding units for slot 1, let's say X. Now, we can calculate the coding unit left for slot 2 (**Ai** - **X**). Using this we can calculate eating unit we can achieve for both slot 1 and slot 2 and compare it with **Bi**. Time complexity for each test case would be O(**Cmax**\***D**). 6 | 7 | ## Test set 2 (Hidden) 8 | 9 | Let's first solve for only 1 day. So assuming two time slots **Si**(**Ei**, **Ci**) and **Sj**(**Ej**, **Sj**) we can see that to achieve every 1 unit of eating in **Si** slot we are losing **Ci**/**Ei** unit of coding, similarly for **Sj** slot. Hence, we can observe that it's always a better choice to choose time slot **Si** if **Ci**/**Ei** ≤ **Cj**/**Ej**. Now, we have the order in which we should achieve the required eating unit. 10 | 11 | For calculating minimum coding requirement we can maintain prefix cumulative and suffix cumulative sum of maximum coding and eating unit that can be achieved in a time slot. Then using binary search on prefix cumulative sum array, we can find out which minimum indexed time slot will give us eating more than required and we can remove the excess fraction of time for use in coding. We can compute the maximum coding unit achieved from unused time slots by using the suffix cumulative sum. This will take O(**S logS** + **S**) preprocessing time and O(**D logS**) for each test case. 12 | -------------------------------------------------------------------------------- /Round B/Building Palindromes/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', inputStdin => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', _ => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map(str => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | function solution() { 24 | const t = Number(readLine()); 25 | for (let i = 0; i < t; i++) { 26 | let [n, q] = readLine() 27 | .split(' ') 28 | .map(Number); 29 | var blocks = readLine().split(''); 30 | let solution = 0; 31 | var precalculated = getPrecalculated(blocks); 32 | 33 | for (let j = 0; j < q; j++) { 34 | let [l, r] = readLine() 35 | .split(' ') 36 | .map(Number); 37 | if (check(precalculated, l - 1, r)) { 38 | solution++; 39 | } 40 | } 41 | 42 | console.log(`Case #${i + 1}: ${solution}`); 43 | } 44 | } 45 | function check(precalculated, l, r) { 46 | const left = l ? precalculated[l - 1] : 0; 47 | const right = precalculated[r - 1]; 48 | return ( 49 | (left ^ right) 50 | .toString(2) 51 | .split('') 52 | .map(Number) 53 | .reduce((a, b) => a + b) <= 1 54 | ); 55 | } 56 | 57 | function getPrecalculated(blocks) { 58 | let precalculated = Array(blocks.length).fill(0); 59 | let curr = 0; 60 | for (let i = 0; i < blocks.length; i++) { 61 | curr = curr ^ (1 << (blocks[i].charCodeAt(0) - 65)); 62 | precalculated[i] = curr; 63 | } 64 | return precalculated; 65 | } 66 | -------------------------------------------------------------------------------- /Round B/Energy Stones/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', inputStdin => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', _ => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map(str => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | function solution() { 24 | const T = Number(readLine()); 25 | for (let t = 0; t < T; t++) { 26 | var n = Number(readLine()); 27 | 28 | var stones = []; 29 | for (let i = 0; i < n; i++) { 30 | let [seconds, energy, lose] = readLine() 31 | .split(' ') 32 | .map(Number); 33 | stones.push({ seconds, energy, lose }); 34 | } 35 | stones.sort((a, b) => a.seconds * b.lose - b.seconds * a.lose); 36 | let max = maxEnergy(stones); 37 | 38 | console.log(`Case #${t + 1}: ${max}`); 39 | } 40 | } 41 | 42 | function maxEnergy(stones) { 43 | let maxTime = stones.reduce((acc, s) => acc + s.seconds, 0); 44 | var dynamicTable = Array(maxTime) 45 | .fill(0) 46 | .map(() => []); 47 | 48 | return maxEnergyAux(0, 0); 49 | 50 | function maxEnergyAux(time, i) { 51 | if (i >= stones.length) { 52 | return 0; 53 | } 54 | 55 | if (dynamicTable[time][i] == undefined) { 56 | let st = stones[i]; 57 | dynamicTable[time][i] = Math.max( 58 | maxEnergyAux(time + st.seconds, i + 1) + Math.max(0, st.energy - st.lose * time), 59 | maxEnergyAux(time, i + 1) 60 | ); 61 | } 62 | return dynamicTable[time][i]; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Round D/X or What?/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | bool isXOdd(int n) 10 | { 11 | int s = false; 12 | while (n) 13 | { 14 | s = s ^ (n % 2); 15 | n /= 2; 16 | } 17 | return s; 18 | } 19 | 20 | int main() 21 | { 22 | /* 23 | Limits: 24 | Time limit: 40 seconds per test set. 25 | Memory limit: 1GB. 26 | 1 ≤ T ≤ 100. 27 | 0 ≤ Ai < 1024. 28 | 0 ≤ Pi < N. 29 | 0 ≤ Vi < 1024. 30 | 31 | Test set 1 (Visible): 32 | 1 ≤ N ≤ 100. 33 | 1 ≤ Q ≤ 100. 34 | 35 | Test set 2 (Hidden): 36 | 1 ≤ N ≤ 10^5. 37 | 1 ≤ Q ≤ 10^5. 38 | */ 39 | int T, N, Q, P, V; 40 | int A; 41 | set xOddPositions; 42 | cin >> T; 43 | 44 | for (int t = 0; t < T; t++) 45 | { 46 | cin >> N >> Q; 47 | xOddPositions.clear(); 48 | for (int i = 0; i < N; i++) 49 | { 50 | cin >> A; 51 | if (isXOdd(A)) 52 | { 53 | xOddPositions.insert(i); 54 | } 55 | } 56 | cout << "Case #" << t + 1 << ":"; 57 | 58 | for (int i = 0; i < Q; i++) 59 | { 60 | cin >> P >> V; 61 | if (isXOdd(V)) 62 | { 63 | xOddPositions.insert(P); 64 | } 65 | else 66 | { 67 | xOddPositions.erase(P); 68 | } 69 | 70 | cout << " "; 71 | if (xOddPositions.size() % 2 == 0) 72 | { 73 | cout << N; 74 | } 75 | else 76 | { 77 | int l = *(xOddPositions.begin()); 78 | int r = *(xOddPositions.rbegin()); 79 | cout << max(r, N - (l + 1)); 80 | } 81 | } 82 | 83 | cout << endl; 84 | } 85 | 86 | return 0; 87 | } -------------------------------------------------------------------------------- /Practice Round/Kickstart Alarm/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', inputStdin => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', _ => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map(str => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | const mod = BigInt(1000000007); 24 | 25 | function solution() { 26 | const T = Number(readLine()); 27 | for (let t = 0; t < T; t++) { 28 | let [N, K, x1, y1, C, D, E1, E2, F] = readLine() 29 | .split(' ') 30 | .map(Number); 31 | const a = Array(N + 1).fill(0); 32 | a[1] = (x1 + y1) % F; 33 | let x; 34 | let y; 35 | for (let i = 2; i <= N; i++) { 36 | x = (C * x1 + D * y1 + E1) % F; 37 | y = (D * x1 + C * y1 + E2) % F; 38 | a[i] = (x + y) % F; 39 | x1 = x; 40 | y1 = y; 41 | } 42 | 43 | let ans = BigInt(0); 44 | let bK = BigInt(K); 45 | let la = bK; 46 | let xx; 47 | for (let i = 2; i <= N + 1; i++) { 48 | ans = (ans + ((((la * BigInt(N + 2 - i)) % mod) * BigInt(a[i - 1])) % mod)) % mod; 49 | xx = ((power(BigInt(i), bK + 1n) - 1n) * power(BigInt(i - 1), mod - 2n)) % mod; 50 | xx--; 51 | if (xx < 0) { 52 | xx += mod; 53 | } 54 | la += xx; 55 | la %= mod; 56 | } 57 | 58 | console.log(`Case #${t + 1}: ${ans}`); 59 | } 60 | } 61 | 62 | function power(x, y) { 63 | let t = 1n; 64 | while (y != 0) { 65 | if (y % 2n == 1n) { 66 | t = (t * x) % mod; 67 | } 68 | x = (x * x) % mod; 69 | y /= 2n; 70 | } 71 | return t; 72 | } 73 | -------------------------------------------------------------------------------- /Round A/Contention/solution_try_2.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', inputStdin => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', _ => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map(str => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | function solution() { 24 | const T = Number(readLine()); 25 | for (let t = 0; t < T; t++) { 26 | let [n, q] = readLine() 27 | .split(' ') 28 | .map(Number); 29 | 30 | const seats = Array(n) 31 | .fill(0) 32 | .map(() => new Set()); 33 | let bookings = []; 34 | for (let j = 0; j < q; j++) { 35 | let [l, r] = readLine() 36 | .split(' ') 37 | .map(Number); 38 | bookings.push({ j, l: l - 1, r: r, rem: 0 }); 39 | for (let k = l - 1; k < r; k++) { 40 | seats[k].add(j); 41 | } 42 | } 43 | 44 | for (let i = 0; i < n; i++) { 45 | if (seats[i].size === 1) { 46 | bookings[seats[i].values().next().value].rem++; 47 | } 48 | } 49 | let sortedBookinns = bookings.slice().sort((b, a) => a.rem - b.rem); 50 | let min = Infinity; 51 | for (let j = 0; j < q; j++) { 52 | let curr = sortedBookinns.shift(); 53 | if (curr.rem < min) { 54 | min = curr.rem; 55 | } 56 | for (let p = curr.l; p < curr.r; p++) { 57 | seats[p].delete(curr.j); 58 | if (seats[p].size === 1) { 59 | bookings[seats[p].values().next().value].rem++; 60 | sortedBookinns.sort((b, a) => a.rem - b.rem); 61 | } 62 | } 63 | } 64 | console.log(`Case #${t + 1}: ${min}`); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Round E/Code-Eat Switcher/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', (inputStdin) => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', (_) => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map((str) => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | function solution() { 24 | const T = Number(readLine()); 25 | for (let t = 0; t < T; t++) { 26 | let [D, S] = readLine().split(/\s+/).map(Number); 27 | let slots = []; 28 | for (let i = 0; i < S; i++) { 29 | let [c, e] = readLine().split(/\s+/).map(Number); 30 | slots.push({ c, e }); 31 | } 32 | slots.sort((a, b) => b.c / b.e - a.c / a.e); 33 | let sums = [{ c: slots[0].c, e: slots[S - 1].e }]; 34 | for (let i = 1; i < S; i++) { 35 | let prev = sums[i - 1]; 36 | sums.push({ c: prev.c + slots[i].c, e: prev.e + slots[S - i - 1].e }); 37 | } 38 | let ans = []; 39 | for (let i = 0; i < D; i++) { 40 | let [a, b] = readLine().split(/\s+/).map(Number); 41 | ans.push(canAchieve(sums, slots, a, b)); 42 | } 43 | console.log(`Case #${t + 1}: ${ans.join('')}`); 44 | } 45 | } 46 | 47 | function canAchieve(sums, slots, a, b) { 48 | let left = 0; 49 | let right = sums.length - 1; 50 | let mid; 51 | while (left <= right) { 52 | mid = (left + right) >> 1; 53 | if (sums[mid].c < a) { 54 | left = mid + 1; 55 | } else { 56 | right = mid - 1; 57 | } 58 | } 59 | if (left >= sums.length) { 60 | return 'N'; 61 | } 62 | let rest = (sums[left].c - a) / slots[left].c; 63 | let eatAvailable = 64 | slots[left].e * rest + (sums[sums.length - 2 - left] ? sums[sums.length - 2 - left].e : 0); 65 | return eatAvailable >= b ? 'Y' : 'N'; 66 | } 67 | -------------------------------------------------------------------------------- /Round F/Teach Me/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | We can solve this test set by considering all ordered pairs of employees. For an ordered pair (i, j), we can check whether there is a skill that the i-th employee knows that the j-th employee does not know with a simple O(**Ci** × **Cj**) check using nested loops. 6 | 7 | This solution runs in O(52 × **N2**). 8 | 9 | ## Test set 2 (Hidden) 10 | 11 | We can solve this test set by defining m(i) as the number of employees who can mentor the i-th employee. If we can compute m(i), the answer to the problem is the sum of all m(i). 12 | 13 | To compute m(i), we can count the number of employees who **cannot** mentor the i-th employee instead. We can observe that the j-th employee cannot mentor the i-th employee if and only if the set of skills known by the j-th employee is a subset of the set of skills known by the i-th employee. Therefore, we would like to count the number of employees whose set of skills is a subset of the set of skills known by the i-th employee. 14 | 15 | To count this, we can consider every subset of {**Ai1**, ..., **AiCi**}. For a subset B, we can count the number of employees whose set of skills is exactly B. Taking the sum of all subsets gives us the number of employees whose set of skills knowledge is the subset of the set of skills known by the i-th employee. m(i) is simply the number of employees subtracted by this value. 16 | 17 | To be able to compute the number of employees whose set of skills is exactly a given set, we can preprocess the set of skills into an occurrences hashmap. In other words, we can keep a hashmap that takes a set of skills as its key and returns the number of employees who knows the exact same set of skills as its value. 18 | 19 | For each employee i, we need to consider every subset of {**Ai1**, ..., **AiCi**}. Since there can be up to 25 subsets, this solutions runs in O(25 × **N**). 20 | -------------------------------------------------------------------------------- /Round F/Flattening/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', (inputStdin) => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', (_) => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map((str) => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | let dpRebuilds = []; 24 | let dp = []; 25 | 26 | function solution() { 27 | const T = Number(readLine()); 28 | for (let t = 0; t < T; t++) { 29 | let [n, k] = readLine().split(' ').map(Number); 30 | dpRebuilds = Array(n) 31 | .fill(null) 32 | .map(() => Array(n).fill(-1)); 33 | dp = Array(n) 34 | .fill(null) 35 | .map(() => Array(k + 1).fill(-1)); 36 | let heights = readLine().split(' ').map(Number); 37 | 38 | console.log(`Case #${t + 1}: ${minRebuildsToK(heights, n - 1, k)}`); 39 | } 40 | } 41 | function minRebuildsToK(heights, x, k) { 42 | if (dp[x][k] === -1) { 43 | if (x == 0) { 44 | dp[x][k] = 0; 45 | } else if (k === 0) { 46 | dp[x][k] = rebuildsToSameHeight(heights, 0, x); 47 | } else { 48 | let min = -1; 49 | for (let i = 0; i < x; i++) { 50 | let tmp = minRebuildsToK(heights, i, k - 1) + rebuildsToSameHeight(heights, i + 1, x); 51 | if (min == -1 || tmp < min) { 52 | min = tmp; 53 | } 54 | } 55 | dp[x][k] = min; 56 | } 57 | } 58 | 59 | return dp[x][k]; 60 | } 61 | function rebuildsToSameHeight(heights, i, j) { 62 | if (i >= j) { 63 | return 0; 64 | } 65 | if (dpRebuilds[i][j] == -1) { 66 | dpRebuilds[i][j] = 67 | j - 68 | i + 69 | 1 - 70 | heights 71 | .slice(i, j + 1) 72 | .sort((a, b) => b - a) 73 | .join(',') 74 | .match(/(\d+)(?:,\1)*/g) 75 | .map((s) => s.split(',').length) 76 | .sort((a, b) => b - a)[0]; 77 | } 78 | return dpRebuilds[i][j]; 79 | } 80 | -------------------------------------------------------------------------------- /Round H/Elevanagram/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', (inputStdin) => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', (_) => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map((str) => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | function solution() { 24 | const T = Number(readLine()); 25 | for (let t = 0; t < T; t++) { 26 | let digits = [0, ...readLine().split(/\s+/).map(Number)]; 27 | console.log(`Case #${t + 1}: ${isMultiplePossible(digits) ? 'YES' : 'NO'}`); 28 | } 29 | } 30 | 31 | function isMultiplePossible(digits) { 32 | let countTen = 0; 33 | let countSix = 0; 34 | let lastTen = -1; 35 | for (let i = 1; i < 10; i++) { 36 | if (digits[i] >= 10) { 37 | countTen++; 38 | lastTen = i; 39 | } 40 | if (digits[i] >= 6) { 41 | countSix++; 42 | } 43 | } 44 | if (countTen >= 2 || countSix >= 3) { 45 | return true; 46 | } 47 | if (lastTen > -1) { 48 | digits[lastTen] = digits[lastTen] % 20; 49 | } 50 | return bt(); 51 | 52 | function bt() { 53 | let a = 0; 54 | let asize = 0; 55 | let fullSize = 0; 56 | let b = 0; 57 | let found = false; 58 | 59 | for (let k = 1; k < digits.length; k++) { 60 | b += digits[k] * k; 61 | fullSize += digits[k]; 62 | } 63 | btAux(1); 64 | return found; 65 | function btAux(i) { 66 | if (found) { 67 | return; 68 | } 69 | if (i == 10) { 70 | if (asize === Math.floor(fullSize / 2)) { 71 | found = Math.abs(a - b) % 11 === 0; 72 | } 73 | return; 74 | } 75 | 76 | for (let k = 0; k <= digits[i]; k++) { 77 | a += k * i; 78 | b -= k * i; 79 | asize += k; 80 | btAux(i + 1); 81 | a -= k * i; 82 | asize -= k; 83 | b += k * i; 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Round H/H-index/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | For a set of papers, let's define a function score(x), which denotes the number of papers in the set with citations at least x. We can calculate the score for every integer x ≤ n, where n is the number of papers in the set. For each set of papers, the answer is maximum x such that score(x) ≥ x. We can store the counts of each of the citation numbers in the input in an array, and calculate cumulative sum to find the score for any x. 6 | 7 | We need to find the maximum x where score(x) ≥ x, each time a new paper is added. We can find that using the approach mentioned above in O(max(**A**)) time, where max(**A**) is the maximum citation number in the set of papers. An observation here is, we can consider all citations ≥ **N** as N, which allows us to find H-index for any set of papers in O(**N**). This leads to a total time complexity of O(**N**2) per test case, which is sufficient for test set 1. 8 | 9 | ## Test set 2 (Hidden) 10 | 11 | For test set 2, we initialize the H-index with 0, and after adding each paper, we need to update the current H-index. We can use a minimum priority queue data structure to store the citation numbers. As we go through each of the papers, we keep updating the current H-index. We also keep updating the priority queue so that it only contains numbers greater than the current H-index and remove the rest. For each new paper, we can follow these steps 12 | 13 | If the current citation number is bigger than the current answer, add it in the priority queue 14 | Remove all the citation numbers from the priority queue which is not greater than the current answer 15 | If the size of priority queue is not less than the current answer + 1, increment the answer by 1 16 | 17 | A single operation of priority queue takes O(log**N**) time, and a number is added and removed at most once. This leads to a total time complexity of O(**N** × log**N**) per test case, which is sufficient for test set 2. 18 | 19 | A solution with linear time complexity is also possible, if we store the citation numbers in an array or a hashtable to calculate the answer. This is left as an exercise for the readers. 20 | -------------------------------------------------------------------------------- /Round H/H-index/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', (inputStdin) => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', (_) => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map((str) => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | let segmentTree; 24 | 25 | function solution() { 26 | const T = Number(readLine()); 27 | for (let t = 0; t < T; t++) { 28 | let N = Number(readLine()); 29 | let citations = readLine().split(/\s+/).map(Number); 30 | segmentTree = Array(2 ** (Math.ceil(Math.log2(1e5 + 1)) + 1)).fill(0); 31 | let hIndex = 0; 32 | let ans = []; 33 | 34 | for (let i = 0; i < citations.length; i++) { 35 | let c = citations[i]; 36 | update(0, 1e5, c); 37 | let right = 1e5; 38 | let mid; 39 | while (hIndex < right) { 40 | mid = (hIndex + right + 1) >> 1; 41 | if (query(0, 1e5, mid) >= mid) { 42 | hIndex = mid; 43 | } else { 44 | right = mid - 1; 45 | } 46 | } 47 | ans.push(hIndex); 48 | } 49 | console.log(`Case #${t + 1}: ${ans.join(' ')}`); 50 | } 51 | } 52 | 53 | function update(start, end, at, node = 0) { 54 | segmentTree[node] += 1; 55 | if (at <= start && end <= at) { 56 | return; 57 | } 58 | let mid = (start + end) >> 1; 59 | if (at <= mid) { 60 | let leftChildNode = (node << 1) | 1; 61 | update(start, mid, at, leftChildNode); 62 | } else { 63 | let rightChildNode = (node + 1) << 1; 64 | update(mid + 1, end, at, rightChildNode); 65 | } 66 | } 67 | 68 | function query(start, end, from, node = 0) { 69 | if (1e5 < start || end < from) { 70 | return 0; 71 | } 72 | if (from <= start && end <= 1e5) { 73 | return segmentTree[node]; 74 | } 75 | let mid = (start + end) >> 1; 76 | 77 | let leftChildNode = (node << 1) | 1; 78 | let rightChildNode = (node + 1) << 1; 79 | return query(start, mid, from, leftChildNode) + query(mid + 1, end, from, rightChildNode); 80 | } 81 | -------------------------------------------------------------------------------- /Round A/Contention/solution_try_1.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', inputStdin => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', _ => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map(str => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | function solution() { 24 | const T = Number(readLine()); 25 | for (let t = 0; t < T; t++) { 26 | let [n, q] = readLine() 27 | .split(' ') 28 | .map(Number); 29 | 30 | let seats = Array(n).fill(0); 31 | 32 | let bookings = []; 33 | for (let j = 0; j < q; j++) { 34 | let [l, r] = readLine() 35 | .split(' ') 36 | .map(Number); 37 | bookings.push({ l: l - 1, r: r, rem: 0 }); 38 | for (let k = l - 1; k < r; k++) { 39 | seats[k]++; 40 | } 41 | } 42 | for (let i = 0; i < n; i++) { 43 | if (seats[i] === 1) { 44 | for (let j = 0; j < q; j++) { 45 | if (bookings[j].l <= i && i < bookings[j].r) { 46 | bookings[j].rem++; 47 | } 48 | } 49 | } 50 | } 51 | 52 | bookings.sort((b, a) => a.rem - b.rem); 53 | let min = Infinity; 54 | for (let j = 0; j < q; j++) { 55 | let curr = bookings.shift(); 56 | if (curr.rem < min) { 57 | min = curr.rem; 58 | } 59 | for (let p = curr.l; p < curr.r; p++) { 60 | seats[p]--; 61 | if (seats[p] === 1) { 62 | for (let k = 0; k < bookings.length; k++) { 63 | if (bookings[k].l <= p && p < bookings[k].r) { 64 | bookings[k].rem++; 65 | let i = k; 66 | let tmp; 67 | while (i > 0 && bookings[i].rem > bookings[i - 1].rem) { 68 | tmp = bookings[i]; 69 | bookings[i] = bookings[i - 1]; 70 | bookings[i - 1] = tmp; 71 | i--; 72 | } 73 | } 74 | } 75 | } 76 | } 77 | } 78 | console.log(`Case #${t + 1}: ${min}`); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Round H/Diagonal Puzzle/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', (inputStdin) => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', (_) => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map((str) => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | function solution() { 24 | const T = Number(readLine()); 25 | for (let t = 0; t < T; t++) { 26 | let N = Number(readLine()); 27 | let square = []; 28 | let visited = Array(4 * N - 2).fill(false); 29 | let graph = Array(4 * N - 2) 30 | .fill(null) 31 | .map(() => []); 32 | for (let i = 0; i < N; i++) { 33 | square.push(readLine().split('')); 34 | } 35 | for (let i = 0; i < N; i++) { 36 | for (let j = 0; j < N; j++) { 37 | let aDiag = N + i - j - 1; 38 | let bDiag = 2 * N + i + j - 1; 39 | let black = square[i][j] === '#'; 40 | graph[aDiag].push({ d: bDiag, black }); 41 | graph[bDiag].push({ d: aDiag, black }); 42 | } 43 | } 44 | console.log(`Case #${t + 1}: ${countMinFlips(graph, visited)}`); 45 | } 46 | } 47 | 48 | function countMinFlips(graph, visited) { 49 | let min = 0; 50 | for (let i = 0; i < visited.length; i++) { 51 | if (!visited[i]) { 52 | min += Math.min( 53 | countFlipsFrom(graph, visited.slice(), i, true), 54 | countFlipsFrom(graph, visited.slice(), i, false) 55 | ); 56 | visitFrom(visited, graph, i); 57 | } 58 | } 59 | return min; 60 | } 61 | 62 | function countFlipsFrom(graph, copyVisited, root, mustFlip) { 63 | let flips = mustFlip; 64 | copyVisited[root] = true; 65 | for (let node of graph[root]) { 66 | if (!copyVisited[node.d]) { 67 | flips += countFlipsFrom(graph, copyVisited, node.d, node.black == mustFlip); 68 | } 69 | } 70 | return flips; 71 | } 72 | function visitFrom(visited, graph, root) { 73 | visited[root] = true; 74 | for (let node of graph[root]) { 75 | if (!visited[node.d]) { 76 | visitFrom(visited, graph, node.d); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Round F/Flattening/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | We can start with an interesting observation - whenever we rebuild a section of the wall, it is equivalent to removing that section. So we can follow two steps, 1. Pick a set of sections of the wall to remove. 2. Check if in the remaining wall sections, the number of positions where **Ai** ≠ **Ai+1** are less than or equals **K**. 6 | 7 | There are 2**N** possible sets of sections, and for each set, checking if the remaining sections will make Blotch happy of not will take O(**N**) time. So the time complexity of this approach is O(2**N** × **N**), which is fast enough for test set 1. 8 | 9 | ## Test set 2 (Hidden) 10 | 11 | We need to approach the problem a bit differently for test set 2. We can start with observing the amount of walls we need to remove for a particular range of consecutive wall sections[i...j]. The most optimal way of making a set of consecutive wall sections have same height would be to figure out which height appeared the most, and remove all sections with a different height. 12 | 13 | So for each consecutive set of walls, we can calculate number of wall removals needed. Let's say, R(i,j) defines number of removals necessary to have all wall sections from i to j have the same height. 14 | 15 | We can define a solution based on a function F(x, k), where F(x, k) denotes the number of the walls we need to remove so that the sections from 1 to x sections in the input has **Ai** ≠ **Ai+1** in at most k places. We can define the recurrence relation as, F(x, k) = min(F(i, k-1) + R(i+1, x)) for all 1 ≤ i ≤ x-1. The minimum number of walls that we need to remove for given **N** and **K** is F(**N**N, **K**). We can compute this function using dynamic programming, which will have O(**N2** × **K**) time complexity, which is fast enough for test 2. 16 | 17 | We can have a faster solution, if we decompose the problem from a slightly different angle. We can think about running binary search on number of removals needed to satisfy the condition. In each iteration of binary search, we need to calculate if it is possible to have k or less number of positions where **Ai** ≠ **Ai+1** if we have at most x removal, x being the value of binary search value of that iteration. That can be also calculated with another dynamic programming, leading us to a solution with time complexity of O(**N2** × log(**N**)). 18 | -------------------------------------------------------------------------------- /Round A/Training/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | To make a fair team, we have to train the members of the team to the same skill level as the most skillful member of the team. 4 | For any **P** students we pick, the time required to make a fair team is = Σ(max(**S**i, **S**i+1... **S**P) - **S**i), for all students i = 1 to **P** in the team. Our goal is to minimize this value. 5 | One possible approach could be to go through all possible subsets of **P** students, from the given **N** students. But there exists **N**C**P** such subsets(here symbol C denotes [Combination](https://en.wikipedia.org/wiki/Combination/)). Number of such subsets will be in the order of [Factorial(N)](https://en.wikipedia.org/wiki/Factorial) and so enumerating through all of them will not fit within the time limit. 6 | 7 | ## Test set 1 (Visible) 8 | 9 | We can start with the observation that once we fix the student with highest skill level x, to minimize our goal we should always choose students with skills as high as possible, but less than or equal to x. Hence we can sort students on the basis of skill level in decreasing order, and iterate over each student assuming they would have the highest skill level in the team. Say, this student is at position i in the sorted sequence; the team would be formed of students on positions i, i + 1, ..., i + **P** - 1 (i.e. a contiguous subarray of size **P**).
10 | For each subarray of size **P** in the sorted array, we can calculate the training time required to make a fair team using the aforementioned formula. There are **N** - **P** + 1 subarrays of size **P**, and the complexity of calculating training time of subarray size **P** is O(**P**). So the overall complexity of this approach is O(**N** × **P**), which will be sufficient for test set 1. 11 | 12 | ## Test set 2 (Hidden) 13 | 14 | We need to go through all of the subarrays once, but can we calculate the training time of a subarray faster?
15 | Let us assume the array is sorted in decreasing order. The training time formula for a subarray starting at position i is
16 | = Σ(**S**[i] - **S**[j]) where j = i to i + **P** -1
17 | = **P** × **S**[i] - Σ(**S**[j]) where j = i to i + **P** - 1
18 | As we always need sum of a contagious subarray, we can pre compute the prefix sum of the whole array in advance, and get the sum of any subarray in O(1) time, which makes the calculation of training time O(1).
19 | So, the overall complexity of this approach is O(**N**). 20 | -------------------------------------------------------------------------------- /Round G/The Equation/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | For the first test set, notice that the maximum value of **k** is 127. This is because each **Ai** is at most 100, so the leading digit of **Ai** is at most 26 = 64. If **k** ≥ 128, then the leading digit of k is at least 27 = 128, meaning that (**Ai** xor k) ≥ 128 > **M**. 6 | 7 | Hence, we can compute the answer by checking each value of **k** less than 128 and finding the largest one which produces a sum less than **M**. 8 | 9 | ## Test set 2 (Hidden) 10 | 11 | For the second test set, the reasoning above tells us that **k** < 250, which is too big for us to check every value. 12 | 13 | Instead, notice that each bit of **k** only affects a single bit of each **Ai**. We can use this property to compute each bit of **k** separately. 14 | 15 | For each 1 ≤ _i_ ≤ 50, define _ones(i)_ to be the number of rules **Ai** with the i-th bit (numbered starting from the least significant bit) equal to 1. Likewise, define _zeroes(i)_ to be the number of rules with the _i_-th bit equal to 0. Then we can re-write the sum: 16 | 17 | Σ1 ≤ j ≤ **N** **Aj** xor **k** 18 | 19 | as: 20 | 21 | Σi : i-th bit of **k** is 1 2i×*zeroes(i)* + Σi : i-th bit of **k** is 0 2i×*ones(i)* 22 | 23 | Note that we can minimize this sum by choosing the i-th bit of **k** to be 1 if _ones(i)_ ≥ _zeroes(i)_, or 0 otherwise. Define _f(j)_ to be the minimum value of the above sum over all bits _i_ ≤ _j_. We can use _f(j)_ to determine if a feasible value of k exists for the lowest j bits, which lets us solve this problem greedily. The greedy solution is as follows: starting from the most significant bit i, check if we can set it to be one (by adding cost of setting this bit to one and _f(i-1)_). If this value is less than or equal to m, there exists a feasible k with the _i_-th bit set to one. Since we want to set to maximize k, it is optimal for us to set this bit to 1. Otherwise, if the sum is larger than m, set the bit to zero. Then iterate by decreasing m by the cost at the current bit and checking the next most significant bit (i-1). In this way, we are able to find the largest feasible k. If _f(i)_ is precomputed, the runtime of this algorithm is O(**N**log(max(**Ai**))). 24 | 25 | Note that since **Ai** ≤ 1015 and **N** ≤ 1000, the maximum sum is a little more than 1018, so using 64-bit integers is sufficient for this problem. 26 | -------------------------------------------------------------------------------- /Round B/Building Palindromes/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | For each query[**L**, **R**], we have to figure out if it is possible to make a palindrome from substring[**L**, **R**] of the original block string. 4 | For any substring, we can create all possible permutations of it and check if any of those is a palindrome. For a substring of length l, in the worst case there would be [Factorial(l)](https://en.wikipedia.org/wiki/Factorial) permutations, and to check if a string of length l is palindrome is O(_l_). So the cost of each query would be O(**N\***Factorial(**N**)) and thus wouldn't fit within the time limit.
5 | One important observation is that in a palindrome, at most one character can appear odd number of times. If more than one character appears odd number of times in a string, it is impossible to rearrange that string to form a palindrome.
6 | If all characters in a string are present even times, we can just divide the characters into two identical sets. Then we can make two strings with those two sets such that one string is the reverse of the other one. Finally concatenate them to get a palindrome.
7 | If we have only one character let's say x, which is present odd number of times, we can set aside one x. Then we get a set of character where all characters are present even number of times, and we can construct a palindrome in somewhat similar way as described above, this time we can just put the x in between those two strings. 8 | 9 | ## Test set 1 (Visible) 10 | 11 | For each query, we can count the frequencies of all characters in the substring and decide if it is possible to make a palindrome or not. The complexity of solving each query in this approach is the length of the substring, which is O(**N**). Total complexity of this approach is O(**N** × **Q**), which will be sufficient for test set 1. 12 | 13 | ## Test set 2 (Hidden) 14 | 15 | We need to count the frequencies of each characters in a query substring, but can we make the counting of frequencies faster? 16 | Notice that, if we calculate prefix sum of frequencies for each character on the whole input string, we can get the frequency of any character in any given substring in O(1) time.
17 | In this approach, the time required to compute the prefix sum of the frequencies for each character is O(**N**) and hence O(**N** × |character set|) for all. And for each query substring, we can check parity of the frequency for each of the characters in O(|character set|) time. So for **Q** queries, the overall complexity of this approach is O((**N + Q**) × |character set|), which is sufficient for test set 2. 18 | -------------------------------------------------------------------------------- /Round D/X or What?/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | Let's define a new array S. We set S0 = 0, S1 = **A1** and Si = Si - 1 xor **Ai** for i = 2 to **N** (Note that S is zero-indexed while **A** is one-indexed). We can see that once we've calculated this, **Al** xor **Al + 1** ... xor **Ar** is simply given by Sr xor Sl - 1. 6 | 7 | With this, Test set 1 can be solved just by calculating the xor sum of every sub-interval of **A** and checking if it's _xor-even_. After each update, we need to recompute S which only takes O(**N**) time. So each query can be handled in O(**N2**) time with an overall complexity of O(**QN2**). 8 | 9 | ## Test set 2 (Hidden) 10 | 11 | Let's extend the definition of _xor-even_ to mean any number having even number of 1s in it's binary representation, similarly for _xor-odd_. Now, notice that if we xor two _xor-even_ numbers or two _xor-odd_ numbers (numbers having an odd number of 1s in their binary representations), we get a _xor-even_ number and, similarly, if we xor a _xor-even_ number with a _xor-odd_ number, we get a _xor-odd_ number. Hence, if there are a even number of _xor-odd_ numbers in an interval then that interval is going to be _xor-even_ and vice versa. 12 | 13 | This means that if there are even number of _xor-odd_ numbers in our array, the whole array is _xor-even_. Otherwise, we consider the subarray starting just after the first _xor-odd_ number and going till the end and the subarray starting from the first element in our array and ending just before the last _xor-odd_ number. Both are _xor-even_ intervals and the larger of them should be the largest _xor-even_ interval in our array. 14 | 15 | We can do this by keeping a set of all positions of _xor-odd_ numbers. Every time we update a number, we simply do an insertion or a deletion or leave the set unchanged. If the size of the set is even, then the whole array is _xor-even_, otherwise we get the left most and the right most positions from this set and output the answer as discussed above. 16 | 17 | Since we will have an O(**N**) elements in the set and there will be **Q** queries, each of O(log(**N**)) time, this solution has a complexity of O((**N+Q**)log(**N**)). 18 | 19 | We can also solve this problem using van [Emde Boas trees](https://en.wikipedia.org/wiki/Van_Emde_Boas_tree) in O(**Q**log(log (**N**))). Or we can use offline algorithms as well to achieve even better asymptotic solutions. Figuring out the details of these approaches is left as exercises to the reader. 20 | -------------------------------------------------------------------------------- /Round A/Contention/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | The number of possible orderings of the requests is [Factorial(Q)](https://en.wikipedia.org/wiki/Factorial), which would not be fast enough for either of the test sets. We can observe that for a chosen ordering of the requests, the number of seats that the system books in the last request does not depend on the ordering of the previous **Q** - 1 requests. So, we could start by finding the request to be processed last and move backwards towards the earlier requests. The answer is the minimum seats booked across the **Q** steps. 4 | 5 | Another observation is that at every step, we can always choose this last request greedily from the remaining set: the one where we can book the maximum number of seats. An intuitive proof of why this works would be noticing that our final answer is non-increasing over the **Q** steps. Now, we can use exchange argument to prove this observation since choosing a request with lesser seats booked would not give us a better answer. 6 | 7 | ## Test set 1 (Visible) 8 | 9 | A naive implementation would be of the order O(**N** × **Q**), where we recalculate number of seats for remaining requests in O(**N**) using [sweep line algorithm](https://en.wikipedia.org/wiki/Sweep_line_algorithm) for each of the **Q** steps. We can speed this up with another observation: the number of unique ranges that the requests cover is at max 2 \* **Q**, which would make our solution run in O(**Q**2) for every test case. 10 | 11 | ### Test set 2 (Hidden) 12 | 13 | Let us try to speed up the slow process of recalculating number of seats we can book at every step For every seat, let us denote the _value_ of a seat as the number of remaining requests trying to book this seat. Everytime the value of a seat drops to 1, we increase the number of seats we can book for the corresponding request containing this seat booking. 14 | 15 | Since requests are represented by an interval, we can use an [interval tree](https://en.wikipedia.org/wiki/Interval_tree) to support the operations of removing an interval after the initial construction of the tree. Each node of the interval tree stores the set of intervals that cover it, and also the minimum value of any seat in it's range. Whenever a remove operation makes the minimum value become one, we walk down the tree to find the seats that became one, and walk back up the tree to find out which interval is the only interval that now covers that seat. We now set that seat's value to infinity so that we don't process it again. This happens only once per seat, for a total amortised cost of O(**N**log**N**). In total this algorithm is O(**N**log(**Q+N**)), if you use a constant time set (like a hashset). 16 | -------------------------------------------------------------------------------- /Round G/Shifts/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | For each shift, we have three choices,
6 | Aninda alone guards the shift
7 | Boon-Nam alone guards the shift
8 | Both of them guard the shift
9 | 10 | We can go through all possible choices for all shifts, and check for how many combinations both of their happiness score is at least **H**. There are total 3**N** such combinations possible, enumerating through all of them fits the time limit for test set 1. 11 | 12 | ## Test set 2 (Hidden) 13 | 14 | For test set 2, we can divide the shifts into 2 sets, each having the size of at most ceil(**N**/2). We can divide them into two sets, because the choices for each shift are independent of each other. For each set, we can enumerate every possible combination, and compute happiness score for both of the guards for each combination, which gives us a list of happiness score pairs for those two sets. Then for each happiness score pair (h1, h2) of the combinations of set 1, we need to count the number of happiness score pairs (p1, p2) of the combinations of set 2, such that p1+h1 ≥ **H** and p2+h2 ≥ **H**, which can be converted to p1 ≥ **H**-h1 and p2 ≥ **H**-h2. 15 | 16 | Essentially, we can follow these steps below to find the answer. 17 | 18 | Store the happiness score pairs of combinations of both set 1 and set 2 in two arrays, let's call them A1 and A2. 19 | Sort both A1 and A2, by the first value in the pair in decreasing order, then by the second value of the pair in decreasing order.
20 | Iterate through A1. For each pair (h1, h2) in A1, do the following:
21 | Find the pairs (p1, p2) in A2 where p1 is not less h1.
22 | For each of the pair (p1, p2) found, add p2 to a data structure.
23 | Find the number of elements not less than h2 in the data structure, add that to answer.
24 | 25 | For this approach, we need a data structure that supports these two operations:
26 | Insert a number in the data structure
27 | Count number of elements in the data structure not less than a given integer
28 | 29 | These two operations can be done in O(log2(X)) time using [range tree](https://en.wikipedia.org/wiki/Range_tree), where X is the number of elements in the data structure. Here upper bound of X is 3(N/2). The total complexity of this approach will be O(3(**N**/2) × log2(3(**N**/2))) ~ O(3(**N**/2) × **N**) which is sufficient for test set 2. 30 | -------------------------------------------------------------------------------- /Round D/Latest Guests/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | For this test set, we simply simulate the entire affair. For each second, we update the positions of all the guests and will add them to the list of latest guests list of the consulate that they visit. We also keep track of the minute when the list for each consulate was updated so that if a guest comes at a later time, we discard the old list and put this guest (and possibly others) to a new list. Finally after the **M**th minute, we iterate through all these lists and find for each guest, how many lists they were a part of and output the answer. This takes a total of O(**G**x(**M+N**)) time which is sufficient for this test set. 6 | 7 | ## Test set 2 (Hidden) 8 | 9 | Let's simplify the problem by assuming all the guests travel clockwise. We can get the final position of each guest after **M** minutes by simply taking their current position, adding **M** to it and finding the modulo of the result with **N**. We categorise the guests into groups based upon their final positions. All guests having the same final positions are in the same group and guests having different final positions are in different groups. We maintain a mapping from guests to groups. We are going to find for each group, how many consulates remember it. 10 | 11 | Now notice that for any consulate only the group whose final position is on or just after it in a clockwise order can be the last visiting group. We can get this by doing a binary search on the sorted list of final positions of the groups or using a sliding window. Note that there can be at most one group which will be remembered by a consulate. 12 | 13 | If this group did not visit this consulate then no one has visited it. To find this we find the time when the group would have visited this consulate last. So we take the difference of their final positions and the position of the consulate and subtract this number from **M**. If the resultant is negative that means no one visited this consulate. Otherwise, for this consulate, we make a note of this group and the time when they visited. 14 | 15 | We handle anti-clockwise guests similarly and get for each consulate the last anti-clockwise guest group to visit it and the time when the group visited. 16 | 17 | Now we iterate through the consulates and see which was the last group to visit it (we include both the clockwise and the anti-clockwise groups). We then increment the number of consulates that remembers this group. Finally, we iterate through the guests and see which group they belong to and output the number of consulates that remember this group. This solution has a run-time of O(**N+G**) if implemented using the sliding window technique or a run-time of O(**G + N**log(**N**)) if we use binary-search instead. 18 | -------------------------------------------------------------------------------- /Round H/Elevanagram/README.md: -------------------------------------------------------------------------------- 1 | # Elevanagram 2 | 3 | ## Solution code 4 | 5 | See [solution source code js](/Round%20H/Elevanagram/solution.js) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20H/Elevanagram/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | It is a well known fact that a number is divisible by 11 if and only if the alternating sum of its digits is equal to 0 modulo 11. For example, 8174958 is a multiple of 11, since 8 - 1 + 7 - 4 + 9 - 5 + 8 = 22. 14 | 15 | Given a number that consists of digits from 1-9, can you rearrange the digits to create a number that is divisible by 11? 16 | 17 | Since the number might be quite large, you are given integers **A1**, **A2**, ..., **A9**. There are **Ai** digits i in the number, for all i. 18 | 19 | ## Input 20 | 21 | The first line of the input gives the number of test cases, **T**. **T** lines follow. Each line contains the nine integers **A1**, **A2**, ..., **A9**. 22 | 23 | ## Output 24 | 25 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is `YES` if the digits can be rearranged to create a multiple of 11, and `NO` otherwise. 26 | 27 | ## Limits 28 | 29 | Time limit: 20 seconds per test set.
30 | Memory limit: 1GB.
31 | 1 ≤ **T** ≤ 100.
32 | 1 ≤ **A1** + **A2** + ... + **A9**. 33 | 34 | ### Test set 1 (Visible) 35 | 36 | 0 ≤ **Ai** ≤ 20, for all i. 37 | 38 | ### Test set 2 (Hidden) 39 | 40 | 0 ≤ **Ai** ≤ 109, for all i. 41 | 42 | ## Sample 43 | 44 | | Input | Output | 45 | | ------------------ | ------------ | 46 | | 6 | | 47 | | 0 0 2 0 0 1 0 0 0 | Case #1: YES | 48 | | 0 0 0 0 0 0 0 0 12 | Case #2: YES | 49 | | 0 0 0 0 2 0 1 1 0 | Case #3: NO | 50 | | 3 1 1 1 0 0 0 0 0 | Case #4: YES | 51 | | 3 0 0 0 0 0 3 0 2 | Case #5: YES | 52 | | 0 0 0 0 0 0 0 1 0 | Case #6: NO | 53 | 54 | - In Sample Case #1, the digits are 336, which can be rearranged to `363`. This is a multiple of 11 since 3 - 6 + 3 = 0. 55 | - In Sample Case #2, the digits are `999999999999`, which is already a multiple of 11, since 9 - 9 + 9 - 9 + ... - 9 = 0. 56 | - In Sample Case #3, the digits are `5578`, which cannot be rearranged to form a multiple of 11. 57 | - In Sample Case #4, the digits are `111234`, which can be rearranged to 142131. This is a multiple of 11 since 1 - 4 + 2 - 1 + 3 - 1 = 0. 58 | - In Sample Case #5, the digits are `11177799`, which can be rearranged to `19191777`. This is a multiple of 11 since 1 - 9 + 1 - 9 + 1 - 7 + 7 - 7 = -22 (which is 0 modulo 11). 59 | - In Sample Case #6, the only digit is `8`, which cannot be rearranged to form a multiple of 11. 60 | -------------------------------------------------------------------------------- /Round G/The Equation/README.md: -------------------------------------------------------------------------------- 1 | # The Equation 2 | 3 | ## Solution code 4 | 5 | See [solution source code js](/Round%20G/The%20Equation/solution.js) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20G/The%20Equation/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | The laws of the universe can be represented by an array of **N** non-negative integers. The i-th of these integers is **Ai**. 14 | 15 | The universe is _good_ if there is a non-negative integer k such that the following equation is satisfied: (**A1** xor k) + (**A2** xor k) + ... (**AN** xor k) ≤ **M**, where xor denotes the [bitwise exclusive or](https://en.wikipedia.org/wiki/Bitwise_operation#XOR). 16 | 17 | What is the largest value of k for which the universe is good? 18 | 19 | ## Input 20 | 21 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case begins with a line containing the two integers **N** and **M**, the number of integers in **A** and the limit on the equation, respectively. 22 | 23 | The second line contains **N** integers, the i-th of which is **Ai**, the i-th integer in the array. 24 | 25 | ## Output 26 | 27 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the largest value of `k` for which the universe is good, or `-1` if there is no such `k`. 28 | 29 | ## Limits 30 | 31 | Time limit: 15 seconds per test set.
32 | Memory limit: 1GB.
33 | 1 ≤ **T** ≤ 100.
34 | 1 ≤ **N** ≤ 100. 35 | 36 | ### Test set 1 (Visible) 37 | 38 | 1 ≤ **M** ≤ 100.
39 | 1 ≤ **Ai** ≤ 100, for all i. 40 | 41 | ### Test set 2 (Hidden) 42 | 43 | 0 ≤ M ≤ 1015. 44 | 0 ≤ Ai ≤ 1015, for all i. 45 | 46 | ## Sample 47 | 48 | | Input | Output | 49 | | ----------- | ------------ | 50 | | 4 | | 51 | | 3 27 | Case #1: 12 | 52 | | 8 2 4 | | 53 | | 4 45 | Case #2: 14 | 54 | | 30 0 4 11 | | 55 | | 1 0 | Case #3: 100 | 56 | | 100 | | 57 | | 6 2 | Case #4: -1 | 58 | | 5 5 1 5 1 0 | | 59 | 60 | In sample case #1, the array contains **N** = 3 integers and **M** = 27. The largest possible value of k that gives a good universe is 12 ((8 xor 12) + (2 xor 12) + (4 xor 12) = 26). 61 | 62 | In sample case #2, the array contains **N** = 4 integers and **M** = 45. The largest possible value of k that gives a good universe is 14 ((30 xor 14) + (0 xor 14) + (4 xor 14) + (11 xor 14) = 45). 63 | 64 | In sample case #3, the array contains **N** = 1 integer and **M** = 0. The largest possible value of k that gives a good universe is 100 (100 xor 100 = 0). 65 | 66 | In sample case #4, there is no value of k that gives a good universe, so the answer is -1. 67 | -------------------------------------------------------------------------------- /Round C/Wiggle Walk/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | Approaching the problem naively, one might try to simply simulate what has been mentioned in the problem statement i.e. keep on moving the robot in the specified direction till it reaches an un-visited square. This approach is going to have a time complexity of O(**N**2), which although good enough for test set 1. 6 | 7 | ## Test set 2 (Hidden) 8 | 9 | The problem with the above approach is that it visits a lot of already visited squares which in worst case will be all the previously visited squares (Consider the input where you are given alternating `E` and `W` throughout). If we somehow get to the destination square for each instruction faster, we might be able to reduce the complexity. 10 | 11 | Let's say the robot is in some row r and received an instruction `W`. Now, all the already visited squares (if any) it will pass before reaching an unvisited square have to form a contiguous interval in row r. This suggests that we may use intervals to represent all the visited squares in the same row. 12 | 13 | With that in mind, consider we have a [set]() of intervals for each row and each column of the grid to represent which cells have been visited in that particular row or column, let's call them interval-sets. Initially, all these sets are empty except for the set corresponding to row **SR**, which has a single interval (**SC**, **SC**), and the set corresponding to the column **SC**, which has a single interval (**SR**, **SR**). 14 | 15 | Now, using this data-structure, let's try to find the destination square for the robot. Let's say it's in square (r, c) and got an instruction W. For this, first we search in the interval-set corresponding to row r. We will try to find which interval in this set contains c (there must definitely be one!). Once we find it, we immediately know what's going to be the new position for the robot! It's apparent that the same method works for all other directions as well. 16 | 17 | All that remains now is to find a way to update our data-structure suitably to also include the newly visited square. This can be done in a very standard manner by simply finding the adjacent intervals for that square in both, the corresponding column interval-set and the corresponding row interval-set and then updating them either by extending one of the intervals or merging them or adding a new 1 length interval. 18 | 19 | Since we add at most one interval in each case, the number of intervals is O(**N**). Since all operations are about finding/inserting/removing a single interval, all of those can be handled easily in O(log(**N**)) time. So the over all run time of this approach is O(**N**log(**N**)). There is also a O(**N**) solution to this problem using hash tables. It is left as an exercise to the reader. 20 | -------------------------------------------------------------------------------- /Round B/Diverse Subarray/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | Consider finding the optimal solution that is a prefix of the input. That is, let us only consider taking ranges of trinkets [1,r] for any r. This reduces the problem to finding prefix sum maximums. For example, consider this sequence of trinkets:
4 | _1, 1, 2, 1, 3, 2, 3, 2, 2_
5 | Assume that **S**=2.
6 | The first and second occurence of a type can be modeled as a +1 event since we can take the trinkets. The **S**+1th occurence can be a -**S** event, since now we cannot take any trinkets of that type. Finally, any further occurence of that type can be a +0 since we still cannot take them. Thus, we have the following events:
7 | _+1, +1, +1, -2, +1, +1, +1, -2, +0_ 8 | A prefix sum ending at index r in our events corresponds to the score for taking the subarray [1,r]. This idea can be generalized to any value of **S**, since all events until the **S**+1th can be +1 events. 9 | 10 | ## Test set 1 (Visible) 11 | 12 | A naive algorithm can be realized using the above strategy. It can be applied to each potential left point (instead of always starting at 1). This explicitly considers every possible range [l,r] and computes the number of trinkets. The events can be calculated by keeping track of how many times each type has occured while sweeping across the trinkets and keeping a running sum of events. The count of types can be handled with a frequency table. Any map from type to count can implement this, for example, an array or hashtable. The strategy uses O(**N**) time to process the solution starting at a particular left point. There are O(**N**) left points. Thus, the time complexity is O(**N**2). This is sufficient for Test set 1. 13 | 14 | ## Test set 2 (Hidden) 15 | 16 | The previous algorithm will not be fast enough for the Test set 2. Observe that the events for the lth left point are closely related to those for the l+1th left point. In particular, only events corresponding to the type of the trinket at index l change. In fact, only the -**S** for that type changes. It moves over to the next +0 event for that type if it exists. The previous -**S** event becomes a +1. This means that the events only change at a constant number of places. 17 | 18 | Using this observation, we can think about this as a data structure problem. We require a data structure that supports two operations: 19 | 20 | Change the value at an index. 21 | What is the maximum prefix sum? 22 | This can be used to maintain our events and find the best solution for each left point respectively. These operations can be achieved using a modified [Segment Tree](https://en.wikipedia.org/wiki/Segment_tree). Each node in the segment tree can be modified to store the sum of the elements covered by that node. Also, each node should store the maximum sum of any prefix of elements that are covered by that node. Such a tree can support both operations in O(log(**N**)) time. We can achieve a final complexity of O(**N** log(**N**)). 23 | -------------------------------------------------------------------------------- /Round C/Circuit Board/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int kadane(int arr[310], int minRow[300], int maxRow[300], int K, int n) 9 | { 10 | 11 | int sum = 0, maxSum = INT_MIN, i; 12 | 13 | // local variable 14 | int local_start = 0; 15 | 16 | int currMin; 17 | int currMax; 18 | for (i = 0; i < n; ++i) 19 | { 20 | if (i == 0) 21 | { 22 | sum = 0; 23 | currMin = minRow[i]; 24 | currMax = maxRow[i]; 25 | } 26 | if (maxRow[i] > currMax) 27 | { 28 | currMax = maxRow[i]; 29 | } 30 | if (minRow[i] > currMin) 31 | { 32 | currMin = minRow[i]; 33 | } 34 | if (currMax - currMin > K) 35 | { 36 | sum = arr[i]; 37 | currMin = minRow[i]; 38 | currMax = maxRow[i]; 39 | } 40 | else 41 | { 42 | sum += arr[i]; 43 | } 44 | 45 | if (sum < 0) 46 | { 47 | sum = 0; 48 | if (i < n) 49 | { 50 | currMin = minRow[i + 1]; 51 | currMax = maxRow[i + 1]; 52 | } 53 | local_start = i + 1; 54 | } 55 | if (sum > maxSum) 56 | { 57 | maxSum = sum; 58 | } 59 | } 60 | 61 | return maxSum; 62 | } 63 | 64 | int main() 65 | { 66 | int T; 67 | int R, C, K; 68 | int board[310][310]; 69 | int maxRow[310]; 70 | int minRow[310]; 71 | int sumRow[310]; 72 | cin >> T; 73 | for (int t = 0; t < T; t++) 74 | { 75 | int maxSum = INT_MIN; 76 | int sum; 77 | 78 | cin >> R >> C >> K; 79 | 80 | for (int i = 0; i < R; i++) 81 | { 82 | for (int j = 0; j < C; j++) 83 | { 84 | cin >> board[i][j]; 85 | } 86 | } 87 | 88 | for (int i = 0; i < C; i++) 89 | { 90 | for (int j = i; j < C; j++) 91 | { 92 | for (int k = 0; k < R; k++) 93 | { 94 | if (i == j) 95 | { 96 | maxRow[k] = board[k][j]; 97 | minRow[k] = board[k][j]; 98 | sumRow[k] = 1; 99 | } 100 | else 101 | { 102 | if (board[k][j] > maxRow[k]) 103 | { 104 | maxRow[k] = board[k][j]; 105 | } 106 | if (board[k][j] < minRow[k]) 107 | { 108 | minRow[k] = board[k][j]; 109 | } 110 | if (maxRow[k] - minRow[k] > K || sumRow[k] < 0) 111 | { 112 | sumRow[k] = INT_MIN; 113 | } 114 | else 115 | { 116 | sumRow[k]++; 117 | } 118 | } 119 | } 120 | sum = kadane(sumRow, minRow, maxRow, K, R); 121 | if (sum > maxSum) 122 | { 123 | maxSum = sum; 124 | } 125 | } 126 | } 127 | 128 | cout << "Case #" << t + 1 << ": " << maxSum << endl; 129 | } 130 | 131 | return 0; 132 | } -------------------------------------------------------------------------------- /Practice Round/Mural/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | We can observe that we will have painted ceil(**N**/2) sections in the end, and all these sections would form a contiguous subarray of the input array. Since painting and destroying is done alternatively, it might not be possible to paint any subarray of our choice. Our objective is to find the maximum subarray sum among the set of "paintable" subarrays. 4 | 5 | ## Small dataset 6 | 7 | An intuitive approach would rely on [Dynamic Programming](https://en.wikipedia.org/wiki/Dynamic_programming) and try to define a DP state that could encapsulate the state of the painted and the destroyed sections at any point in time. Note that painted section is contiguous, and the destroyed sections are prefixes and suffixes of the input array. 8 | Hence, we can define _f(i, j, l, r)_ as the maximum possible achievable score if _i_ and _j_ are the lengths of the destroyed prefix and suffix, respectively; whereas _l_ and _r_ denote the left and the right boundaries of the painted subarray. A recurrence can easily be derived by considering at most four further possibilities: we have two ways to extend the mural (by painting the section either to the left or to the right of the already painted boundary), and two ways to extend the destroyed part (either the prefix or the suffix).
9 | Note that it would seem that there are O(**N**4) different valid states in the above approach, but that is not the case since the sum of lengths of painted and destroyed parts is always the same. We can get rid of the index of the right boundary of the painted subarray (i.e. variable _r_), as it can be implicitly derived from the variables _i_ and _j_. 10 | The overall complexity of this approach is O(**N**3) and that will suffice for the Small dataset. 11 | 12 | ## Large dataset 13 | 14 | The solution to the Large dataset relies on an interesting observation that all possible contiguous subarrays of length ceil(**N**/2) are "paintable". If we can prove this fact, we can simply do an O(**N**) rolling window approach over all such subarrays and output the maximum possible sum. 15 | 16 | Let's think of an intuitive way to prove this. Say, if we paint the i-th section on the first day, what could be the smallest possible index of the left boundary of the mural in the worst case? To achieve the smallest possible index, we will always extend the boundary on the left side; and in the worst case the flood can always extend the prefix, allowing us to paint only the indices after index _ceil(i/2)_(inclusive). And similarly, there would be an upper limit on the maximum possible index of the right boundary.
17 | This means that given the desirable left boundary of the mural, we can figure out the "central point" from which we would begin painting. Now, irrespective of the sequence of destructions, we can always meet the desirable left boundary by always extending our subarray to the left whenever a section on the left is destroyed. Similar arguments can be applied to the right boundary. 18 | -------------------------------------------------------------------------------- /Round G/Shifts/README.md: -------------------------------------------------------------------------------- 1 | # Shifts 2 | 3 | ## Solution code 4 | 5 | See [solution source code js](/Round%20G/Shifts/solution.js) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20G/Shifts/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Aninda and Boon-Nam are security guards at a small art museum. Their job consists of **N** shifts. During each shift, at least one of the two guards must work. 14 | 15 | The two guards have different preferences for each shift. For the i-th shift, Aninda will gain **Ai** happiness points if he works, while Boon-Nam will gain **Bi** happiness points if she works. 16 | 17 | The two guards will be happy if both of them receive at least **H** happiness points. How many different assignments of shifts are there where the guards will be happy? 18 | 19 | Two assignments are considered different if there is a shift where Aninda works in one assignment but not in the other, or there is a shift where Boon-Nam works in one assignment but not in the other. 20 | 21 | ## Input 22 | 23 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case begins with a line containing the two integers **N** and **H**, the number of shifts and the minimum happiness points required, respectively. The second line contains **N** integers. The i-th of these integers is **Ai**, the amount of happiness points Aninda gets if he works during the i-th shift. The third line contains **N** integers. The i-th of these integers is **Bi**, the amount of happiness points Boon-Nam gets if she works during the i-th shift. 24 | 25 | ## Output 26 | 27 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the number of different assignments of shifts where the guards will be happy. 28 | 29 | ## Limits 30 | 31 | Time limit: 40 seconds per test set.
32 | Memory limit: 1GB.
33 | 1 ≤ **T** ≤ 100.
34 | 0 ≤ **H** ≤ 109.
35 | 0 ≤ **Ai** ≤ 109.
36 | 0 ≤ **Bi** ≤ 109. 37 | 38 | ### Test set 1 (Visible) 39 | 40 | 1 ≤ **N** ≤ 12. 41 | 42 | ### Test set 2 (Hidden) 43 | 44 | 1 ≤ **N** ≤ 20. 45 | 46 | ## Sample 47 | 48 | | Input | Output | 49 | | ----- | ---------- | 50 | | 2 | | 51 | | 2 3 | Case #1: 3 | 52 | | 1 2 | | 53 | | 3 3 | | 54 | | 2 5 | Case #2: 0 | 55 | | 2 2 | | 56 | | 10 30 | | 57 | 58 | In Sample Case #1, there are **N** = 2 shifts and **H** = 3. There are three possible ways for both Aninda and Boon-Nam to be happy: 59 | 60 | - Only Aninda works on the first shift, while both Aninda and Boon-Nam work on the second shift. 61 | - Aninda and Boon-Nam work on the first shift, while only Aninda works on the second shift. 62 | - Both security guards work on both shifts. 63 | 64 | In Sample Case #2, there are **N** = 2 shifts and **H** = 5. It is impossible for both Aninda and Boon-Nam to be happy, so the answer is 0. 65 | -------------------------------------------------------------------------------- /Round C/Catch Some/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | Firstly, observe that if Bundle switches the color of her shirt then she should never wear a previously worn color again as that would not give us a better answer. Also, for dogs of the same color, if she observes one dog then she should have observed all dogs who are at a position less than that dog. The condition that she doesn't need to return to her home after observing the last dog is a little tricky. Let's first solve the problem where she must return home after observing the last dog. 6 | 7 | For this simplified version, we notice that the order of the color of shirts that Bundle has to put on doesn't matter. This gives rise to the following dynamic programming approach. 8 | Let dp[i][j] denote the minimum time Bundle needs to observe j dogs such that she has either observed or has decided she'll not observe dogs of colors 1 to i. 9 | Hence, dp[C][**k**] becomes our answer, where C is the total number of different colors. 10 | 11 | To calculate dp[i][j] we loop upon the number of dogs Bundle could have observed for the (i-1)th color, and take the minimum cost among them. That is, 12 | dp[i][j] = min(dp[i-1][j] + 0, dp[i-1][j-1] + 2 _ Xi,1, dp[i-1][j-2] + 2 _ Xi, 2, dp[i-1][j-3] + 2 \* Xi, 3 ...) 13 | Where, Xc, d represents the distance of the d-th dog of c-th color from Bundle's house. 14 | 15 | Since the size of the loop for a particular color is the number of dogs of previous color + 1, the sum of sizes of all loops is O(**N**). Hence, we have O(**N**2) states and do a total of O(**N**) transitions. This gives us a run time of O(**N**2) for a given color as the last color. 16 | 17 | To complete the solution, we simply do this considering every color as the last color and add in the cost of observing dogs of the last color separately. This will incur an additional O(**N**) loop to iterate over all colors resulting in a final complexity of O(**N**3). 18 | 19 | ## Test set 2 (Hidden) 20 | 21 | We can optimize the previous solution to not do the same calculations with every color as the last color. This can be done by adding a boolean parameter in our state representing if we have already decided on the last color. We simply don't add the cost of returning back home whenever we set this parameter to true. 22 | 23 | Essentially, we have dp[i][j][k] where i and j still represent the same things and k is a boolean denoting if we have chosen the last color in the first i colors. 24 | 25 | Now, dp[i][j][0] = min(dp[i-1][j][0] + 0, dp[i-1][j-1][0] + 2 _ Xi,1, dp[i-1][j-2][0] + 2 _ Xi, 2 ...) 26 | 27 | dp[i][j][1] = min(min(dp[i-1][j][1] + 0, dp[i-1][j-1][1] + 2 _ Xi,1, dp[i-1][j-2][1] + 2 _ Xi, 2 ...), 28 | min(dp[i-1][j][0] + 0, dp[i-1][j-1][0] + Xi,1, dp[i-1][j-2][0] + Xi, 2 ...)) 29 | 30 | Again we have O(**N**2) states and do a total of O(**N**) transitions. But we just do this once and not once for every color, yielding a final complexity of O(**N**2). 31 | -------------------------------------------------------------------------------- /Round A/Training/README.md: -------------------------------------------------------------------------------- 1 | # Training 2 | 3 | ## Solution code 4 | 5 | See [solution source code](/Round%20A/Training/solution.js) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20A/Training/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | As the football coach at your local school, you have been tasked with picking a team of exactly **P** students to represent your school. There are **N** students for you to pick from. The i-th student has a _skill rating_ **Si**, which is a positive integer indicating how skilled they are. 14 | 15 | You have decided that a team is _fair_ if it has exactly **P** students on it and they all have the same skill rating. That way, everyone plays as a team. Initially, it might not be possible to pick a fair team, so you will give some of the students one-on-one coaching. It takes one hour of coaching to increase the skill rating of any student by 1. 16 | 17 | The competition season is starting very soon (in fact, the first match has already started!), so you'd like to find the minimum number of hours of coaching you need to give before you are able to pick a fair team. 18 | 19 | ## Input 20 | 21 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case starts with a line containing the two integers **N** and **P**, the number of students and the number of students you need to pick, respectively. Then, another line follows containing **N** integers **Si**; the i-th of these is the skill of the i-th student. 22 | 23 | ## Output 24 | 25 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the minimum number of hours of coaching needed, before you can pick a fair team of **P** students. 26 | 27 | ## Limits 28 | 29 | Time limit: 15 seconds per test set.
30 | Memory limit: 1 GB.
31 | 1 ≤ **T** ≤ 100.
32 | 1 ≤ **Si** ≤ 10000, for all i.
33 | 2 ≤ **P** ≤ **N**.
34 | 35 | ### Test set 1 (Visible) 36 | 37 | 2 ≤ **N**≤ 1000. 38 | 39 | ### Test set 2 (Hidden) 40 | 41 | 2 ≤ **N** ≤ 105. 42 | 43 | ## Sample 44 | 45 | | Input | Output | 46 | | ----------- | ----------- | 47 | | 3 | | 48 | | 4 3 | Case #1: 14 | 49 | | 3 1 9 100 | | 50 | | 6 2 | Case #2: 0 | 51 | | 5 5 1 2 3 4 | | 52 | | 5 5 | Case #3: 6 | 53 | | 7 7 1 7 7 | | 54 | 55 | In Sample Case #1, you can spend a total of 6 hours training the first student and 8 hours training the second one. This gives the first, second and third students a skill level of 9. This is the minimum time you can spend, so the answer is 14. 56 | 57 | In Sample Case #2, you can already pick a fair team (the first and second student) without having to do any coaching, so the answer is 0. 58 | 59 | In Sample Case #3, **P** = **N**, so every student will be on your team. You have to spend 6 hours training the third student, so that they have a skill of 7, like everyone else. This is the minimum time you can spend, so the answer is 6. 60 | -------------------------------------------------------------------------------- /Round G/Book Reading/README.md: -------------------------------------------------------------------------------- 1 | # Book Reading 2 | 3 | ## Solution code 4 | 5 | See [solution source code c++](/Round%20G/Book%20Reading/solution.cpp) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20G/Book%20Reading/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Supervin is a librarian handling an ancient book with **N** pages, numbered from 1 to **N**. Since the book is too old, unfortunately **M** pages are torn out: page number **P1**, **P2**, ..., **PM**. 14 | 15 | Today, there are **Q** lazy readers who are interested in reading the ancient book. Since they are lazy, each reader will not necessarily read all the pages. Instead, the i-th reader will only read the pages that are numbered multiples of **Ri** and not torn out. Supervin would like to know the sum of the number of pages read by each reader. 16 | 17 | ## Input 18 | 19 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case begins with a line containing the three integers **N**, **M**, and **Q**, the number of pages in the book, the number of torn out pages in the book, and the number of readers, respectively. The second line contains **M** integers, the i-th of which is **Pi**. The third line contains **Q** integers, the i-th of which is **Ri**. 20 | 21 | ## Output 22 | 23 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the total number of pages that will be read by all readers. 24 | 25 | ## Limits 26 | 27 | Time limit: 40 seconds per test set.
28 | Memory limit: 1GB.
29 | 1 ≤ **T** ≤ 100.
30 | 1 ≤ **P1** < **P2** < ... < **PM** ≤ **N**.
31 | 1 ≤ **Ri** ≤ **N**, for all i. 32 | 33 | ### Test set 1 (Visible) 34 | 35 | 1 ≤ **M** ≤ **N** ≤ 1000.
36 | 1 ≤ **Q** ≤ 1000. 37 | 38 | ### Test set 2 (Hidden) 39 | 40 | 1 ≤ **M** ≤ **N** ≤ 105.
41 | 1 ≤ **Q** ≤ 105. 42 | 43 | ## Sample 44 | 45 | | Input | Output | 46 | | ----------------------- | ------------ | 47 | | 3 | | 48 | | 11 1 2 | Case #1: 7 | 49 | | 8 | | 50 | | 2 3 | | 51 | | 11 11 11 | Case #2: 0 | 52 | | 1 2 3 4 5 6 7 8 9 10 11 | | 53 | | 1 2 3 4 5 6 7 8 9 10 11 | | 54 | | 1000 6 1 | Case #3: 994 | 55 | | 4 8 15 16 23 42 | | 56 | | 1 | | 57 | 58 | In sample case #1, the first reader will read the pages numbered 2, 4, 6, and 10. Note that the page numbered 8 will not be read since it is torn out. The second reader will read the pages numbered 3, 6, and 9. Therefore, the total number of pages that will be read by all readers is 4 + 3 = 7. 59 | 60 | In sample case #2, all pages are torn out so all readers will read 0 pages. 61 | 62 | In sample case #3, the first reader will read all the pages other than the six given pages. 63 | -------------------------------------------------------------------------------- /Round F/Spectating Villages/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | Since there are very few villages for this set, we can calculate the sum of beauty values of illuminated villages for every possible set of villages we choose to build lighthouses in and then take the maximum among these. 6 | 7 | For each such set, we have to find which villages will be illuminated. So, for each village, we see if it is in the set or if any of its neighbours are in the set and add its beauty value accordingly. 8 | 9 | Since there will be 2**V** such sets and for each such set we are taking O(**V**) time to figure out what is the corresponding total beauty value for the set, the overall complexity of this approach is O(**V**2**V**) 10 | 11 | ## Test set 2 (Hidden) 12 | 13 | The the graph formed by taking the villages as nodes and roads as edges is a tree. Let's root this tree at node number 1. 14 | 15 | Now, let us define a function maxBeauty(K, P, Q) which represents the maximum beauty value we can obtain from nodes in the subtree of node K (including itself) such that P is a boolean indicating whether the parent node of K has a lighthouse and Q is a boolean indicating whether K itself has a lighthouse. The solution to our problem is simply max(maxBeauty(1, 0, 1), maxBeauty(1, 0, 0)). We consider a few cases to evaluate maxBeauty(K, P, Q). 16 | 17 | If Q = 1, then we have a lighthouse placed at K. Which means all of its children will be illuminated irrespective of them having a lighthouse or not. Therefore, in this case, 18 | maxBeauty(K, P, Q) = **B**K + sum of max(maxBeauty(C, 1, 0), maxBeauty(C, 1, 1)) for all children C of node K. 19 | 20 | If Q = 0 and P = 1, then irrespective of whatever we choose for the children of K, they are not going to recieve light from K but K itself is going to be illuminated. Therefore, in this case, 21 | maxBeauty(K, P, Q) = **B**K + sum of max(maxBeauty(C, 0, 0), maxBeauty(C, 0, 1)) for all children C of node K. 22 | 23 | Else, we have Q = 0 and P = 0. This means that the children of K are not going to recieve light from K but the illumination of K depends on whether we place a lighthouse in at least one of the children of K. 24 | This case can be handled using a dynamic programming approach. We define dp[i][j] as maximum sum of beauty values of all illuminated nodes in the first i subtrees of node K such that, if j = 0 then we have not placed a lighthouse in any of the first i children of K and if j = 1 then there is at least one node among the first i children of K with a lighthouse. 25 | Therefore, dp[i][0] = dp[i-1][0] + maxBeauty(Ci, 0, 0) and 26 | dp[i][1] = max(dp[i - 1][1] + max(maxBeauty(Ci, 0, 0), maxBeauty(Ci, 0, 1)), dp[i - 1][0] + maxBeauty(Ci, 0, 1)). 27 | (Here, Ci represents the ith child of K) 28 | Finally, for this case, maxBeauty(K, P, Q) = max(dp[M][1] + **B**K, dp[M][0]) where M is the total number of children of K. 29 | 30 | Since for every node K we can get maxBeauty(K, P, Q) for all values of P and Q in O(M) time, overall complexity of this approach is O(**N**). 31 | -------------------------------------------------------------------------------- /Round H/Elevanagram/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | We need to divide each digits to two partitions: positive partition and negative partition, where positive partition means the digit is on the odd index (be calculated as _add_), and negative partition means the digit is in the even index (be calculated as _minus_). 6 | 7 | We can use dynamic programming to solve test set 1. Let dp[i][j][k] denote if it is possible to achieve the state that when we are considering digits 1, 2, ... i, the current number of digits in the positive partition is j and the current sum modulo 11 is k. Then for each digit i, we can put 0, 1, ..., **Ai** digits into the positive partition, and calculate if the current state is possible. We want to calculate dp[9][sum(**a**)/2][0], where sum(**A**) means the total sum of all elements in array **A**. 8 | 9 | The time complexity is O(9 _ sum(**A**) _ 11 \* max(**A**)), which fits the time limit for test case 1. Here max(**A**) means the maximum of all elements in array **A**. 10 | 11 | ## Test set 2 (Hidden) 12 | 13 | Assume the positive number of digits i is Pi, and negative number of digits i is **Ai** - Pi. Then, we will have the following three equations: 14 | 15 |
16 |   (1) Σ Pi = ceil(sum(A) / 2)
17 |   (2) Σ i × (Pi - (Ai - Pi)) % 11 = 0
18 |   (3) 0 ≤ PiAi
19 | 
20 | 21 | In order to solve this, initially we can put half the number of each digits to be in positive partition (e.g. Pi = **Ai** / 2, take care of odd numbers), and then try to adjust each Pi to satisfy equation (2). For each i, we can adjust its Pi from -**Ai** / 2 to **Ai** / 2. 22 | 23 | We can prove the two following conclusions: 24 | 25 | 1. If there are at least two numbers of **Ai** ≥ 10, then the solution must exist. 26 | 27 | This is very easy to prove. We can only adjust these two digits from -5 to 5, and each adjustment will result in a different remain value of modulo 11. Thus, we will get 0 finally. 28 | 29 | 1. If there are at least three numbers of **Ai** ≥ 6, then the solution must exist. 30 | 31 | To prove this, we can prove that: 32 | 33 |
34 |    For any 1 ≤ i < j < k ≤ 9, 0 ≤ r ≤ 10, the following equations:
35 |    (1) (i * x1 + j * x2 + k * x3) % 11 = r
36 |    (2) x1 + x2 + x3 = 0
37 |    (3) -3 ≤ xi ≤ 3
38 |    will have a valid solution.
39 |    
40 | 41 | This can be proved by iterating all possible situations, where the total number is 9**C**3 \* 11 \* 7 \* 7 = 45276, quite small. 42 | 43 | According to these two conclusions, if there are at least two numbers ≥ 10 or at least three numbers ≥ 6, we can return YES immediately. Otherwise, there are at most one value ≥ 10, and at most two values ≥ 6, we can calculate all possible situations, where in the worst case time complexity is O(67 \* 10) = O(2799360) which fits the time limit for test case 2. 44 | -------------------------------------------------------------------------------- /Round H/H-index/README.md: -------------------------------------------------------------------------------- 1 | # H-index 2 | 3 | ## Solution code 4 | 5 | See [solution source code js](/Round%20H/H-index/solution.js) 6 | 7 | See [alternative solution source code c++](/Round%20H/H-index/solution.cpp) 8 | 9 | ## Analysis 10 | 11 | You can see [solution analysis](/Round%20H/H-index/analysis.md) extracted from Google webpage. 12 | 13 | ## Problem 14 | 15 | It is important for researchers to write many high quality academic papers. Jorge has recently discovered a way to measure how impactful a researcher's papers are: the [H-index](https://en.wikipedia.org/wiki/H-index). 16 | 17 | The _H-index score_ of a researcher is the largest integer h such that the researcher has h papers with at least h citations each. 18 | 19 | Jorge has written **N** papers in his lifetime. The i-th paper has **Ai** citations. The number of citations that each paper has will never change after it is written. Please help Jorge determine his H-index score after each paper he wrote. 20 | 21 | ## Input 22 | 23 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case begins with a line containing **N**, the number of papers Jorge wrote. 24 | 25 | The second line contains **N** integers. The i-th integer is **Ai**, the number of citations the i-th paper has. 26 | 27 | ## Output 28 | 29 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is a space-separated list of integers. The i-th integer is the H-index score after Jorge wrote his i-th paper. 30 | 31 | ## Limits 32 | 33 | Time limit: 50 seconds per test set.
34 | Memory limit: 1GB.
35 | 1 ≤ **T** ≤ 100.
36 | 1 ≤ **Ai** ≤ 105. 37 | 38 | ### Test set 1 (Visible) 39 | 40 | 1 ≤ **N** ≤ 1000. 41 | 42 | ### Test set 2 (Hidden) 43 | 44 | 1 ≤ **N** ≤ 105. 45 | 46 | ## Sample 47 | 48 | | Input | Output | 49 | | ------------ | -------------------- | 50 | | 2 | | 51 | | 3 | Case #1: 1 1 2 | 52 | | 5 1 2 | | 53 | | 6 | Case #2: 1 1 2 2 2 3 | 54 | | 1 3 3 2 2 15 | | 55 | 56 | In Sample Case #1, Jorge wrote **N** = 3 papers. 57 | 58 | - After the 1st paper, Jorge's H-index score is 1, since he has 1 paper with at least 1 citation. 59 | - After the 2nd paper, Jorge's H-index score is still 1. 60 | - After the 3rd paper, Jorge's H-index score is 2, since he has 2 papers with at least 2 citations (the 1st and 3rd papers). 61 | 62 | In Sample Case #2, Jorge wrote **N** = 6 papers. 63 | 64 | - After the 1st paper, Jorge's H-index score is 1, since he has 1 paper with at least 1 citation. 65 | - After the 2nd paper, Jorge's H-index score is still 1. 66 | - After the 3rd paper, Jorge's H-index score is 2, since he has 2 papers with at least 2 citations (the 2nd and 3rd papers). 67 | - After the 4th paper, Jorge's H-index score is still 2. 68 | - After the 5th paper, Jorge's H-index score is still 2. 69 | - After the 6th paper, Jorge's H-index score is 3, since he has 3 papers with at least 3 citations (the 2nd, 3rd and 6th papers). 70 | -------------------------------------------------------------------------------- /Round C/Wiggle Walk/README.md: -------------------------------------------------------------------------------- 1 | # Wiggle Walk 2 | 3 | ## Solution code 4 | 5 | See [solution source code c++](/Round%20C/Wiggle%20Walk/solution.cpp) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20C/Wiggle%20Walk/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Banny has just bought a new programmable robot. Eager to test his coding skills, he has placed the robot in a grid of squares with **R** rows (numbered 1 to **R** from north to south) and **C** columns (numbered 1 to **C** from west to east). The square in row r and column c is denoted (r, c). 14 | 15 | Initially the robot starts in the square (**SR**, **SC**). Banny will give the robot **N** instructions. Each instruction is one of `N`, `S`, `E` or `W`, instructing the robot to move one square north, south, east or west respectively. 16 | 17 | If the robot moves into a square that it has been in before, the robot will continue moving in the same direction until it reaches a square that it _has not_ been in before. Banny will never give the robot an instruction that will cause it to move out of the grid. 18 | 19 | Can you help Banny determine which square the robot will finish in, after following the **N** instructions? 20 | 21 | ## Input 22 | 23 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case starts with a line containing the five integers **N**, **R**, **C**, **SR** and **SC**, the number of instructions, the number of rows, the number of columns, the robot's starting row and starting column, respectively. 24 | 25 | Then, another line follows containing a single string of **N** characters; the i-th of these characters is the i-th instruction Banny gives the robot (one of `N`, `S`, `E` or `W`, as described above). 26 | 27 | ## Output 28 | 29 | For each test case, output one line containing `Case #x: r c`, where `x` is the test case number (starting from 1), `r` is the row the robot finishes in and `c` is the column the robot finishes in. 30 | 31 | ## Limits 32 | 33 | Memory limit: 1GB.
34 | 1 ≤ **T** ≤ 100.
35 | 1 ≤ **R** ≤ 5 × 104.
36 | 1 ≤ **C** ≤ 5 × 104.
37 | 1 ≤ **SR** ≤ **R**.
38 | 1 ≤ **SC** ≤ **C**.
39 | The instructions will not cause the robot to move out of the grid. 40 | 41 | ### Test set 1 (Visible) 42 | 43 | Time limit: 20 seconds.
44 | 1 ≤ **N** ≤ 100. 45 | 46 | ### Test set 2 (Hidden) 47 | 48 | Time limit: 60 seconds.
49 | 1 ≤ **N** ≤ 5 × 104. 50 | 51 | ## Sample 52 | 53 | | Input | Output | 54 | | ----------- | ------------ | 55 | | 3 | | 56 | | 5 3 6 2 3 | Case #1: 3 2 | 57 | | EEWNS | | 58 | | 4 3 3 1 1 | Case #2: 3 3 | 59 | | SESE | | 60 | | 11 5 8 3 4 | Case #3: 3 7 | 61 | | NEESSWWNESE | | 62 | 63 | Sample Case #1 corresponds to the top-left diagram, Sample Case #2 corresponds to the top-right diagram and Sample Case #3 corresponds to the lower diagram. In each diagram, the yellow square is the square the robot starts in, while the green square is the square the robot finishes in. 64 | 65 | ![Wiggle Walk](/images/round-c-wiggle-walk.png) 66 | -------------------------------------------------------------------------------- /Round H/Diagonal Puzzle/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | For a square grid of size **N**, there's total 2 × **N** − 1 diagonals that are parallel to the main diagonal, and 2 × **N** − 1 diagonals that are perpendicular to the main diagonal. 6 | 7 | For each of the diagonals parallel to the main diagonal, we can fix either we would flip them or not, and then check if each of the perpendicular diagonals contain cells of the same color. If all cells are the same for each of the perpendicular diagonals, then this would lead to a solution. If all white, just flip the whole diagonal, if not, nothing is necessary. 8 | 9 | There are total 22 × **N** − 1 possible combinations for flipping diagonals parallel to the main diagonal, and we can check if the perpendicular diagonals have all same coloured cells in O(**N**2) time complexity, which leads to a total time complexity of O(22 × **N** − 1 × **N**2) per test case, which is sufficient for test set 1. 10 | 11 | ## Test set 2 (Hidden) 12 | 13 | One interesting observation is that if we decide whether we would flip the two largest diagonals or not, we can pick all other diagonals to flip deterministically. There are four choices for flipping/not flipping the largest two diagonals. And for each of these choices, we can go through all other diagonals in the grid. For each of these other diagonals, we can check if the cell where it intersected with one of the largest diagonals is white. If it's white, we need to flip this diagonal, otherwise not. For each of those four combinations of the largest diagonal flips, if after all the flips(both largest two diagonals and others), the final state has all black cells, then we have a possible answer, otherwise not. We take the minimum flips of the four possible choices. 14 | 15 | There are 4 choices for the flipping of the two largest diagonals. And for each of the choices, the flipping of all other diagonals, and finally checking for all black cells can be done in O(**N**2) time, which leads to a total time complexity of O(**N**2), which is sufficient for test set 2. 16 | 17 | An alternative solution is to convert this problem into a variant of [2-coloring](https://en.wikipedia.org/wiki/Graph_coloring#Vertex_coloring). Each of the cells in the grid is shared by two diagonals. If a cell is white, either one of them needs to be flipped to make this cell black. Otherwise, none of these two diagonals needs to be flipped. For this problem, we can consider each diagonal as a vertex of a graph, and and the squares in the grid are the edges between the two diagonals that affect that square. If the square is initially black, then the endpoints of the corresponding edge must be colored the same, else they must be colored differently. By color, we mean chosen to be flipped or not flipped. So we should color in such a way that all conditions for all edges in the graph are satisfied and we have the minimum number of flips possible. This can be done with a DFS for each component of the graph. 18 | 19 | There are total O(**N**2) edges in the graph. Building the graph and solving it can be done in O(|Edges|). This leads to a time complexity of O(**N**), which is sufficient for test set 2. 20 | -------------------------------------------------------------------------------- /Round E/Cherries Mesh/README.md: -------------------------------------------------------------------------------- 1 | # Cherries Mesh 2 | 3 | ## Solution code 4 | 5 | See [solution source code c++](/Round%20E/Cherries%20Mesh/solution.cpp) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20E/Cherries%20Mesh/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Your friend is recently done with cooking class and now he wants to boast in front of his school friends by making a nice dessert. He has come up with an amazing dessert called Cherries Mesh. To make the dish, he has already collected cherries numbered 1 to **N**. He has also decided to connect each distinct and unordered pair of cherries with a sweet strand, made of sugar. Sweet strands are either red or black, depending on the sugar content in them. Each black strand contains one units of sugar, and each red strand contains two units of sugar. 14 | 15 | But it turns out that the dessert is now too sweet, and these days his school friends are dieting and they usually like dishes with less sugar. He is really confused now and comes to your rescue. Can you help him find out which all sweet strands he should remove such that each pair of cherries is connected directly or indirectly via a sugar strand, and the dish has the minimum possible sugar content? 16 | 17 | ## Input 18 | 19 | The first line of input gives the number of test cases, **T**. 20 | 21 | Each test case begins with a line containing two integers **N** and **M**, the number of cherries and the number of _black_ sweet strands, respectively. 22 | 23 | Then **M** lines follow, each describing a pair of cherries connected to a black strand. The i-th line contains cherries numbered **Ci** and **Di**, it indicates that **Ci** and **Di** cherry are connected with a black strand of sugar. 24 | 25 | Note: Any other pair of cherries not present in the input means that they are connected by a red strand. 26 | 27 | ## Output 28 | 29 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is minimum possible sugar content. 30 | 31 | ## Limits 32 | 33 | Time limit: 15 seconds per test set.
34 | Memory limit: 1GB.
35 | 1 ≤ **T** ≤ 100.
36 | **M** ≤ **N\***(**N**-1)/2
37 | 1 ≤ **Ci** ≤ **N**, for all i.
38 | 1 ≤ **Di** ≤ **N**, for all i.
39 | **Ci** ≠ **Di**, for all i.
40 | Every {**Ci**, **Di**} is distinct. 41 | 42 | ### Test set 1 (Visible) 43 | 44 | 2 ≤ **N** ≤ 100.
45 | 1 ≤ **M** ≤ 100. 46 | 47 | ### Test set 2 (Hidden) 48 | 49 | For at least 90% of the test cases:
50 | 1 ≤ **N** ≤ 1000.
51 | 0 ≤ **M** ≤ 1000. 52 | 53 | For all test cases:
54 | 1 ≤ **N** ≤ 105. 55 | 0 ≤ **M** ≤ 105. 56 | 57 | ## Sample 58 | 59 | | Input | Output | 60 | | ----- | ---------- | 61 | | 2 | | 62 | | 2 1 | Case #1: 1 | 63 | | 1 2 | | 64 | | 3 1 | Case #2: 3 | 65 | | 2 3 | | 66 | 67 | In the first sample case, there are two cherries and they are connected with a black strand. Removing any of the strand causes cherries to get disconnected. Hence, the minimum sugar content is 1. 68 | 69 | In the second sample case, we can keep the black strand between cherry numbered 2 and cherry numbered 3, and remove any of the red strands, which leads to a minimum sugar content of 3. 70 | -------------------------------------------------------------------------------- /Round E/Street Checkers/README.md: -------------------------------------------------------------------------------- 1 | # Street Checkers 2 | 3 | ## Solution code 4 | 5 | See [solution source code c++](/Round%20E/Street%20Checkers/solution.cpp) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20E/Street%20Checkers/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Alice and Bob are playing a new virtual reality team game - Street Checkers. The game is set on a very long street divided into tiles which are numbered from 0 to 109(inclusive of both). At the start of the game, Alice and Bob are standing on tile number 0 and are given a random number X in range [**L**, **R**] (both ends are inclusive). Alice only jumps to odd numbered tiles, while Bob only jumps to even numbered tiles. If the number on the tile divides X, then the player landing on it has to color it with their favorite color. The game is over after tile X has been colored. 14 | 15 | A game is considered interesting by both the players if the absolute difference between the number of tiles painted by each is not greater than 2. Help Alice and Bob find how many numbers in the interval [**L**, **R**] could make for an interesting game. 16 | 17 | ## Input 18 | 19 | The first line of the input gives the number of test cases, **T**. **T** lines follow each containing two integers **L** and **R**, the start and end of the interval used to generate the random number X. 20 | 21 | ## Output 22 | 23 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the count of numbers in interval [**L**, **R**] which results in an interesting game for Alice and Bob. 24 | 25 | ## Limits 26 | 27 | Time limit: 40 seconds per test set.
28 | Memory limit: 1GB.
29 | 1 ≤ **T** ≤ 100.
30 | 0 ≤ **R - L** ≤ 105. 31 | 32 | ### Test set 1 (Visible) 33 | 34 | 1 ≤ **L** ≤ **R** ≤ 106. 35 | 36 | ### Test set 2 (Hidden) 37 | 38 | 1 ≤ **L** ≤ **R** ≤ 109. 39 | 40 | ## Sample 41 | 42 | | Input | Output | 43 | | ------- | ---------- | 44 | | 2 | | 45 | | 5 10 | Case #1: 5 | 46 | | 102 102 | Case #2: 1 | 47 | 48 | For the first sample case, let us look at all the possible number in range [5, 10]: 49 | 50 | - 5 - Alice would paint 2 tiles : {1, 5}, and Bob would not paint any tile. The game would be interesting since the absolute difference is 2. 51 | - 6 - Alice would paint 2 tiles : {1, 3}, and Bob would paint 2 tiles : {2, 6}. The game would be interesting since the absolute difference is 0. 52 | - 7 - Alice would paint 2 tiles : {1, 7}, and Bob would not paint any tile. The game would be interesting since the absolute difference is 2. 53 | - 8 - Alice would paint 1 tile : {1}, and Bob would paint 3 tiles : {2, 4, 8}. The game would be interesting since the absolute difference is 2. 54 | - 9 - Alice would paint 2 tiles : {1, 3, 9}, and Bob would not paint any tile. The game would not be interesting since the absolute difference is greater than 2. 55 | - 10 - Alice would paint 2 tiles : {1, 5}, and Bob would paint 2 tiles : {2, 10}. The game would be interesting since the absolute difference is 0. 56 | 57 | Thus, the answer for this test case is 5. 58 | 59 | In the second sample case, we have only one number 102. Alice would paint 4 tiles : {1, 3, 17, 51} while Bob would paint 4 tiles : {2, 6, 34, 102}. The game would be interesting since the absolute difference is 0. 60 | -------------------------------------------------------------------------------- /Round C/Catch Some/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | long long int dp[1001][1001][2]; 9 | vector positionsByColor[1001]; 10 | 11 | long long int getMinSecsToObserveKDogsWithIColors(int color, int k, int selectedLastColor) 12 | { 13 | if (dp[color][k][selectedLastColor] < 0) 14 | { 15 | long long int minWithout, minWith, tmp, sk; 16 | if (!selectedLastColor) 17 | { 18 | minWithout = color > 0 ? getMinSecsToObserveKDogsWithIColors(color - 1, k, selectedLastColor) : INT_MAX; 19 | sk = 1; 20 | for (auto it = positionsByColor[color].begin(); it != positionsByColor[color].end() && sk <= k; it++) 21 | { 22 | tmp = (*it) * 2L + getMinSecsToObserveKDogsWithIColors(color - 1, k - sk, selectedLastColor); 23 | if (tmp < minWithout) 24 | { 25 | minWithout = tmp; 26 | } 27 | sk++; 28 | } 29 | dp[color][k][selectedLastColor] = minWithout; 30 | } 31 | else 32 | { 33 | minWith = color > 0 ? min(getMinSecsToObserveKDogsWithIColors(color - 1, k, selectedLastColor), getMinSecsToObserveKDogsWithIColors(color - 1, k, 1 - selectedLastColor)) : INT_MAX; 34 | sk = 1; 35 | for (auto it = positionsByColor[color].begin(); it != positionsByColor[color].end() && sk <= k; it++) 36 | { 37 | tmp = (*it) + getMinSecsToObserveKDogsWithIColors(color - 1, k - sk, 1 - selectedLastColor); 38 | if (tmp < minWith) 39 | { 40 | minWith = tmp; 41 | } 42 | 43 | tmp = (*it) * 2 + getMinSecsToObserveKDogsWithIColors(color - 1, k - sk, selectedLastColor); 44 | if (tmp < minWith) 45 | { 46 | minWith = tmp; 47 | } 48 | sk++; 49 | } 50 | dp[color][k][selectedLastColor] = minWith; 51 | } 52 | } 53 | 54 | return dp[color][k][selectedLastColor]; 55 | } 56 | 57 | int main() 58 | { 59 | /* 60 | Limits: 61 | 1 ≤ T ≤ 100. 62 | 1 ≤ K ≤ N. 63 | 1 ≤ Ai ≤ 1000. 64 | 1 ≤ Pi ≤ 105. 65 | 66 | Test set 1 (Visible): 67 | 1 ≤ N ≤ 50. 68 | 69 | Test set 2 (Hidden): 70 | 1 ≤ N ≤ 1000. 71 | */ 72 | int T, N, K, color; 73 | int positions[1001]; 74 | cin >> T; 75 | 76 | for (int t = 0; t < T; t++) 77 | { 78 | cin >> N >> K; 79 | for (int i = 0; i < 1001; i++) 80 | { 81 | positionsByColor[i].clear(); 82 | for (int j = 0; j < 1001; j++) 83 | { 84 | if (j == 0) 85 | { 86 | dp[i][j][0] = 0; 87 | dp[i][j][1] = 0; 88 | } 89 | else 90 | { 91 | dp[i][j][0] = (i == 0 ? INT_MAX : -1); 92 | dp[i][j][1] = (i == 0 ? INT_MAX : -1); 93 | } 94 | } 95 | } 96 | for (int i = 0; i < N; i++) 97 | { 98 | cin >> positions[i]; 99 | } 100 | for (int i = 0; i < N; i++) 101 | { 102 | cin >> color; 103 | positionsByColor[color].push_back(positions[i]); 104 | } 105 | for (int i = 0; i < 1001; i++) 106 | { 107 | sort(positionsByColor[i].begin(), positionsByColor[i].end()); 108 | } 109 | 110 | cout << "Case #" << t + 1 << ": " << getMinSecsToObserveKDogsWithIColors(1000, K, 1) << endl; 111 | } 112 | 113 | return 0; 114 | } -------------------------------------------------------------------------------- /Practice Round/Kickstart Alarm/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | The problem asks us to calculate the summation of power of each wakeup call: POWER1 + POWER2 + ... + POWER**K**, where POWERi is just the summation of the i-th exponential-power of all the contiguous subarrays of the Parameter Array. 4 | 5 | ## Small dataset 6 | 7 | For Small dataset, you can iterate over every subarray of the given array and calculate the summation of POWERi for all i ≤ **K**. Thus, the simplest brute solution will work for Small dataset. 8 | 9 | Psuedocode for Small dataset: 10 | 11 | ``` 12 | result = 0 13 | for(k in 1 to K) { 14 | for(L in 1 to N) { 15 | for(R in L to N) { 16 | for(j in L to R) { 17 | result = result + A[j] * pow(j-L+1,k) 18 | result %= 1000000007 19 | } 20 | } 21 | } 22 | } 23 | ``` 24 | 25 | The overall time complexity is O(**N**3 \* **K**). 26 | 27 | ## Large dataset 28 | 29 | The above solution wont work for Large dataset. To solve for Large dataset, let's iterate over every position x and calculate the contribution by Ax to the result for all subarrays ending at x. 30 | 31 | Suppose Ax is the first and only element in the subarray. Then we need to add Ax _ 11 + Ax _ 12 ... Ax _ 1**K** to the result.
32 | Suppose Ax is the second and last element in the subarray. Then we need to add Ax _ 21 + Ax _ 22 ... Ax _ 2**K** to the result.
33 | Suppose Ax is the third and last element in the subarray. Then we need to add Ax _ 31 + Ax _ 32 ... Ax _ 3**K** to the result.
34 | Similary, looking at the pattern, if Ax is the pth element in the subarray, we need to add Ax _ p1 + Ax _ p2 ... Ax _ p**K** to the result.
35 | If you look closely at the last expression, you will notice that it's the summation of a geometric progression. So it can also be written as Ax _ (p**K**+1 -1)/(p - 1). The value of p can be from 2 to x, since x is supposed to be the last element of the subarray. Note that we need to handle the p = 1 case separately since the above expression isn't valid for p = 1. For p = 1, we will simply add Ax _ **K** to the expression.
36 | Thus the summation of the power of each wakeup call is simply Σ Ax _ (**K** + (p**K**+1 -1)/(p - 1)) for all 2 ≤ p ≤ x and 1 ≤ x ≤ **N**. But if you implement an O(**N**2 _ log(**K**)) solution for this by iterating over each x and p, and using fast exponentiation, it won't be fast enough. We can use the fact that for a fixed value of x, we just need to calculate Ax \* Σ (**K** + (p**K**+1 - 1)/(p - 1)) for 2 ≤ p ≤ x. Note that multiplicand for x can be derived in constant time from the multiplicand in case of x - 1. See the pseudo code below. 37 | 38 | ``` 39 | result = 0 40 | GP_sum = K # Handling p = 1 case separately. 41 | mod = 1000000007 42 | for(x in 1 to N) { 43 | if x != 1 44 | GP_sum = GP_sum + (pow(x, K+1)-1) * pow(x-1, mod-2) # Multipyting by inverse modulo of x-1. 45 | GP_sum %= mod 46 | 47 | result = result + GP_sum * A[x] 48 | result %= mod 49 | } 50 | ``` 51 | -------------------------------------------------------------------------------- /Round C/Circuit Board/README.md: -------------------------------------------------------------------------------- 1 | # Circuit Board 2 | 3 | ## Solution code 4 | 5 | See [solution source code c++](/Round%20C/Circuit%20Board/solution.cpp) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20C/Circuit%20Board/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Arsh recently found an old rectangular circuit board that he would like to recycle. The circuit board has **R** rows and **C** columns of squares. 14 | 15 | Each square of the circuit board has a thickness, measured in millimetres. The square in the r-th row and c-th column has thickness **Vr,c**. A circuit board is good if in each row, the difference between the thickest square and the least thick square is no greater than **K**. 16 | 17 | Since the original circuit board might not be good, Arsh would like to find a good subcircuit board. A subcircuit board can be obtained by choosing an axis-aligned subrectangle from the original board and taking the squares in that subrectangle. Arsh would like your help in finding the number of squares in the largest good subrectangle of his original board. 18 | 19 | ## Input 20 | 21 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case begins with one line containing three integers **R**, **C** and **K**, the number of rows, the number of columns, and the maximum difference in thickness allowed in each row. 22 | 23 | Then, there are **R** more lines containing **C** integers each. The c-th integer on the r-th line is **Vr, c**, the thickness of the square in the r-th row and c-th column. 24 | 25 | ## Output 26 | 27 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the maximum number of squares in a good subrectangle. 28 | 29 | ## Limits 30 | 31 | Time limit: 15 seconds per test set.
32 | Memory limit: 1GB.
33 | 1 ≤ **T** ≤ 50.
34 | 1 ≤ **R** ≤ 300.
35 | 1 ≤ **C** ≤ 300.
36 | 0 ≤ **Vi, j** ≤ 103 for all i, j. 37 | 38 | ### Test set 1 (Visible) 39 | 40 | **K** = 0. 41 | 42 | ### Test set 1 (Hidden) 43 | 44 | 0 ≤ **K** ≤ 103. 45 | 46 | ## Sample 47 | 48 | | Input 1 | Output 1 | 49 | | ---------- | ---------- | 50 | | 3 | | 51 | | 1 4 0 | Case #1: 2 | 52 | | 3 1 3 3 | | 53 | | 2 3 0 | Case #2: 2 | 54 | | 4 4 5 | | 55 | | 7 6 6 | | 56 | | 4 5 0 | Case #3: 6 | 57 | | 2 2 4 4 20 | | 58 | | 8 3 3 3 12 | | 59 | | 6 6 3 3 3 | | 60 | | 1 6 8 6 4 | | 61 | 62 | | Input 2 | Output 2 | 63 | | ----------- | ---------- | 64 | | 3 | | 65 | | 1 4 2 | Case #1: 4 | 66 | | 3 1 3 3 | | 67 | | 3 3 2 | Case #2: 3 | 68 | | 0 5 0 | | 69 | | 8 12 3 | | 70 | | 7 10 1 | | 71 | | 4 4 8 | Case #3: 4 | 72 | | 20 10 20 10 | | 73 | | 10 4 5 20 | | 74 | | 20 5 4 10 | | 75 | | 10 20 10 20 | | 76 | 77 | Note: Sample 2 is not valid for Test set 1. Sample 1 will be tested prior to running Test set 1 (the same way samples normally are). However, Sample 2 will **not** be tested prior to running Test set 2. 78 | 79 | The sample cases are illustrated below. For each case, the good subcircuit board with the largest number of squares is highlighted in green. 80 | 81 | ![Circuit Board](/images/round-c-circuit-board.png) 82 | -------------------------------------------------------------------------------- /Round E/Street Checkers/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | Let's rephrase the problem into counting the number of **X**'s within the range [**L**, **R**] that satisfies |(# of odd divisors) - (# of even divisors)| ≤ 2. 6 | 7 | To solve this problem under the constraint that **R** < 106. We can simply preprocesses each **X** between 1 and 106 whether **X** is interesting or not. To find whether **X** is interesting, we can apply any O(√**X**) time algorithm finding out all divisors of **X**. After storing the result for each **X**, we build a prefix sum array **F** storing for counts. Thus, each query can be answered by computing **F[R] - F[L-1]** in constant time. The total time complexity would then be O(**Rmax√Rmax + T**), which suffices to pass the first test set. 8 | 9 | ## Test set 2 (Hidden) 10 | 11 | We need a slightly sophisticated observation here. The intuition comes from observing that any divisor to an odd integer is still odd. For any integer **X** we can extract all power of 2 factors and rewrite as **X=A\*2B**, where **A** is an odd integer and **B** is a nonnegative integer. 12 | 13 | Now, we can partition all divisors to **X** into sets of divisors leading with each odd divisors **d1**, **d2**, ..., **dk** of **A**: 14 | 15 | {**d1**, **d1**\*2, **d1**\*22, ..., **d1**\*2B},
16 | {**d2**, **d2**\*2, **d2**\*22, ..., **d2**\*2B},
17 | ...
18 | {**dk**, **dk**\*2, **dk**\*22, ..., **dk**\*2B}. 19 | 20 | By looking at the above diagram we can infer that **X** has **k** odd divisors and **k**\***B** even divisors. The criteria to a number being interesting is now equivalent to |**k**\*(**B**-1)| ≤ 2. 21 | 22 | There are only a few cases of (**B**, **k**) pairs that satisfies the above expression: 23 | 24 | Case 1: **B**=0, **k**=1 or 2.
25 | Case 2: **B**=1, **k** can be any value.
26 | Case 3: **B**=2, **k**=1 or 2.
27 | Case 4: **B**=3, **k**=1. 28 | 29 | So, what we really need to do here is to count the number of **X**'s in the range [**L**, **R**] satisfying each case. 30 | 31 | Case 1 implies that **X**=1 or a odd prime. One can count the number of primes within range [**L**, **R**] using [Sieve of Eratosthenes](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes). Case 2 implies that **A** can be any odd integer, so in this case **X** is in the form of (4\***K**+2) and hence can be counted in O(1) time. Case 3 implies that **A**=1 or an odd prime. One can count the number of primes within range [**L**/4, **R**/4]. Case 4 implies that **X**=8. Count it whenever 8 belongs to the range. 32 | 33 | From the above case analysis, one can see that the running time is dominated by Sieve of Eratosthenes. Fortunately, we only need to use sieve method on arrays of size O(**R**-**L**+1) to count the number of odd primes within ranges [**L**, **R**] and [**L**/4, **R**/4]. If we apply sieving using numbers 2, 3, 4, ..., √**R**, the algorithm runs in O(**T**\*(**R** - **L** + 1)\*log(√**R**)) time, which suffices to pass this test set. 34 | 35 | For a more efficient algorithm, one can sieve using prime numbers no more than √**R**. These prime numbers again can be obtained by a sieving algorithm. At the end you will get an algorithm that runs in O(√**R** log log √**R**) + O((**R** - **L** + 1) log log √**R**) time per test case. 36 | -------------------------------------------------------------------------------- /Round B/Energy Stones/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | For this test set, it is guaranteed that **Si** = **Sj** for all i, j. For simplicity, we will assume that we never eat a stone with zero energy. Consider two energy stones i and j that will be eaten back-to-back. If **Li** > **Lj** then we should eat i before j. This is because stone i loses energy faster than j, so taking it first will result in a smaller overall loss of energy. 6 | 7 | Thus, no matter which set of energy stones are eaten, that set should be eaten in non-increasing value of **Li**. So we should first sort the stones by **Li** and then the only decision to be made is which stones should be eaten and which should not be eaten. This reduces the problem to a [0/1 Knapsack](https://en.wikipedia.org/wiki/Knapsack_problem) problem. This can be solved with [dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming). 8 | 9 | Define `max_energy(time, i)` as the maximum total energy that can be achieved given the current time and considering only the suffix of energy stones sorted in decreasing **Li** from i to **N**. The recurrence relation for this function considers two cases. Either take the i-th energy stone (with its energy adjusted by the time), or do not take it. So, `max_energy(time, i)` is the maximum of: 10 | max_energy(time+**Si**, i+1) +max(0,**Ei** - **Li** _ time)
11 | max_energy(time,i+1)
12 | The maximum possible time is the sum of all **Si** because an optimal strategy might eat all the stones and will not use any time waiting. Call this sum(**S**). The time complexity of this approach can be described as O(**N** _ sum(**S**)). This is fast enough for both test sets. However, sorting energy stones by **Li** is incorrect for Test set 2. 13 | 14 | ## Test set 2 (Hidden) 15 | 16 | We will need to find a different way to order the energy stones to solve Test set 2. As before, consider two energy stones i and j assuming that we can take both i and j without either going to zero energy. We know that **Si** might not equal **Sj**. However, there is an ordering for taking both i and j that is always optimal. Observe that **Si** _ **Lj** is the total loss of energy if i is used first. Likewise, **Sj** _ **Li** is the loss if j is used first. Thus, if **Si** _ **Lj** < **Sj** _ **Li** then taking i first leads to a smaller overall loss of energy. It may not be obvious that we should always take i before j even if it leads to a smaller loss of energy. This is because there may be other stones between i and j in some potential ordering. However, if i and j are adjacent in some ordering, then we will achieve more energy by swapping them if **Si** _ **Lj** > **Sj** _ **Li**. Applying this rule iteratively will eventually sort the stones. Therefore, this rule defines an ordering on our energy stones. If our assumption about neither stone going to zero energy is not true, then the order of i and j does not matter. In that case, the only decision is what stones we eat. Thus, we can use the dynamic programming solution from Test set 1 to solve Test set 2 with the same time complexity. 17 | 18 | The reader may have noticed that this sort order is equivalent to comparing fractions; it is the same as sorting by **Si**/**Li**. However, one must be careful when **Li**=0. 19 | -------------------------------------------------------------------------------- /Round A/Parcels/README.md: -------------------------------------------------------------------------------- 1 | # Parcels 2 | 3 | ## Solution code 4 | 5 | See [solution source code](/Round%20A/Parcels/solution.js) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20A/Parcels/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | You have been hired recently as the Chief Decision Maker (CDM) at a famous parcel delivery company, congratulations! Customers love speedy deliveries of their parcels and you have decided to decrease the time it takes to deliver parcels around the world to win customers. You have introduced this idea to the authorities and they have allocated you enough budget to build at most one new delivery office. 14 | 15 | The world can be divided into an **R** × **C** grid of squares. Each square either contains a delivery office or it does not. You may pick a grid square that does not already contain a delivery office and build a new delivery office there. 16 | 17 | The delivery time of a parcel to a square is 0 if that square contains a delivery office. Otherwise, it is defined as the minimum Manhattan distance between that square and any other square containing a delivery office. The overall delivery time is the maximum of delivery times of all the squares. What is the minimum overall delivery time you can obtain by building at most one new delivery office? 18 | 19 | Note: The [Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry) between two squares (r1,c1) and (r2,c2) is defined as |r1 - r2| + |c1 - c2|, where |\*| operator denotes the absolute value. 20 | 21 | ## Input 22 | 23 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. The first line of each test case contains the number of rows **R** and number of columns **C** of the grid. Each of the next **R** lines contains a string of **C** characters chosen from the set `{0, 1}`, where `0` denotes the absence of a delivery office and `1` denotes the presence of a delivery office in the square. 24 | 25 | ## Output 26 | 27 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the minimum overall delivery time you can obtain after adding at most one additional delivery office. 28 | 29 | ## Limits 30 | 31 | Time limit: 15 seconds per test set.
32 | Memory limit: 1GB.
33 | 1 ≤ **T** ≤ 100.
34 | There is at least one delivery office in the initial grid.
35 | 36 | ### Test set 1 (Visible) 37 | 38 | 1 ≤ **R** ≤ 10.
39 | 1 ≤ **C** ≤ 10. 40 | 41 | ### Test set 2 (Hidden) 42 | 43 | 1 ≤ **R** ≤ 250.
44 | 1 ≤ **C** ≤ 250. 45 | 46 | ## Sample 47 | 48 | | Input | Output | 49 | | ----- | ---------- | 50 | | 3 | | 51 | | 3 3 | Case #1: 1 | 52 | | 101 | | 53 | | 000 | | 54 | | 101 | | 55 | | 1 2 | Case #2: 0 | 56 | | 11 | Case #3: 2 | 57 | | 5 5 | | 58 | | 10001 | | 59 | | 00000 | | 60 | | 00000 | | 61 | | 00000 | | 62 | | 10001 | | 63 | 64 | In Sample Case #1, you get a minimum overall delivery time of 1 by building a new delivery office in any one of the five squares without a delivery office. 65 | 66 | In Sample Case #2, all the squares already have a delivery office and so the minimum overall delivery time is 0. Note you have to add **at most** one delivery office. 67 | 68 | In Sample Case #3, to get a minimum overall delivery time of 2, you can build a new delivery office in any of these squares: (2, 3), (3, 2), (3, 3), (3, 4), or (4, 3). Any other possibility results in a higher overall delivery time than 2. 69 | -------------------------------------------------------------------------------- /Round A/Contention/solution_small_test_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | struct Booking 9 | { 10 | int l; 11 | int r; 12 | int rem; 13 | int j; 14 | bool deleted = false; 15 | }; 16 | 17 | int main() 18 | { 19 | std::ios_base::sync_with_stdio(false); 20 | int T; 21 | int n, q, l, r; 22 | cin >> T; 23 | set bExtremes; 24 | set currBookings; 25 | 26 | struct Booking bookings[30000]; 27 | struct Booking *startBookings[30000]; 28 | struct Booking *endBookings[30000]; 29 | 30 | for (int t = 0; t < T; t++) 31 | { 32 | cin >> n >> q; 33 | 34 | bExtremes.clear(); 35 | currBookings.clear(); 36 | 37 | bExtremes.insert(0); 38 | bExtremes.insert(n); 39 | 40 | for (int i = 0; i < q; i++) 41 | { 42 | cin >> l >> r; 43 | bookings[i] = {.l = l - 1, .r = r, .rem = 0, .j = i, .deleted = false}; 44 | startBookings[i] = &bookings[i]; 45 | endBookings[i] = &bookings[i]; 46 | bExtremes.insert(l - 1); 47 | bExtremes.insert(r); 48 | } 49 | sort(startBookings, startBookings + q, [](struct Booking *a, struct Booking *b) { return a->l < b->l; }); 50 | sort(endBookings, endBookings + q, [](struct Booking *a, struct Booking *b) { return a->r < b->r; }); 51 | 52 | int min = INT_MAX; 53 | std::set::iterator it; 54 | 55 | struct Booking *maxBooking; 56 | int maxRem = INT_MIN; 57 | int s = 0; 58 | int e = 0; 59 | int currEx; 60 | int k = 0; 61 | for (int i = 0; i < q; i++) 62 | { 63 | 64 | for (int k = 0; k < q; k++) 65 | { 66 | bookings[k].rem = 0; 67 | } 68 | maxBooking = NULL; 69 | maxRem = INT_MIN; 70 | currBookings.clear(); 71 | it = bExtremes.begin(); 72 | currEx = *it; 73 | ++it; 74 | s = 0; 75 | e = 0; 76 | for (; it != bExtremes.end(); ++it) 77 | { 78 | while (e < q && endBookings[e]->r == currEx) 79 | { 80 | if (!endBookings[e]->deleted) 81 | { 82 | currBookings.erase(endBookings[e]->j); 83 | if (bookings[endBookings[e]->j].rem > maxRem) 84 | { 85 | maxRem = bookings[endBookings[e]->j].rem; 86 | maxBooking = &(bookings[endBookings[e]->j]); 87 | } 88 | } 89 | e++; 90 | } 91 | while (s < q && startBookings[s]->l == currEx) 92 | { 93 | if (!startBookings[s]->deleted) 94 | { 95 | currBookings.insert(startBookings[s]->j); 96 | if (bookings[startBookings[s]->j].rem > maxRem) 97 | { 98 | maxRem = bookings[startBookings[s]->j].rem; 99 | maxBooking = &(bookings[startBookings[s]->j]); 100 | } 101 | } 102 | s++; 103 | } 104 | if (currBookings.size() == 1) 105 | { 106 | int j = *currBookings.begin(); 107 | bookings[j].rem += *it - currEx; 108 | if (bookings[j].rem > maxRem) 109 | { 110 | maxRem = bookings[j].rem; 111 | maxBooking = &(bookings[j]); 112 | } 113 | } 114 | currEx = *it; 115 | } 116 | maxBooking->deleted = true; 117 | if (maxBooking->rem < min) 118 | { 119 | min = maxBooking->rem; 120 | } 121 | } 122 | 123 | cout << "Case #" << t + 1 << ": " << min << endl; 124 | } 125 | return 0; 126 | } -------------------------------------------------------------------------------- /Round D/Food Stalls/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | We will start by fixing the position of the warehouse. Once that is done, we know the cost of putting up a stall at any spot. This allows for a dynamic programming approach where we let dp[i][j] represent the cost of putting j stalls in the first i spots. dp[i][j] is minimum of dp[i - 1][j] and (dp[i-1][j-1] + distance of ith spot from warehouse + **Ci**) (we skip i if we have chosen to place the warehouse at i). dp[N][**k**] + cost of building the warehouse represents our solution for the chosen location of the warehouse. 6 | 7 | By doing this for all possible positions for the warehouse, we will get the minimum cost for placing all **K** stalls. So this approach has a complexity of O(**N2K**). 8 | 9 | ## Test set 2 (Hidden) 10 | 11 | Now suppose we decided on the **K** + 1 spots where we will place our stalls and warehouse but are yet to decide where to place our warehouse, let's say the co-ordinates of these spots are Y1, Y2, ..., YK + 1 in increasing order. Obviously, it'll be the spot Yj such that |Yj - Y1| + |Yj - Y2| + ... |Yj - YK + 1| is minimum. This is the classic post office location problem and is solved by putting the warehouse in the median point of our chosen points (in case of even number of points with two medians, any one will yield an optimal answer). 12 | 13 | Once we have this observation, we know that we must put floor(**K**/2) stalls on the left of our warehouse and **K**-floor(**K**/2) stalls on the right. If we can calculate, for every position of the warehouse, the minimum cost to place these points, we will be done. Here we will show how to calculate the minimum cost to place floor(**K**/2) stalls to the left of every position of the warehouse. 14 | 15 | For simplicity, we assume the given points X1, X2, ..., XN to be sorted. Now, we will maintain a max-heap of size floor(K/2). For position i, we define Vi = XN - Xi + **Ci**. Initially, we will store V1, V2, ..., Vfloor(**K**/2) in our heap. We'll also maintain the sum of all the elements in our heap. 16 | 17 | If we consider that we are placing the warehouse at **X**floor(**K**/2)+1, then the minimum cost of placing all floor(**K**/2) stalls to the left of it is given by sum of all the elements in our heap - floor(**K**/2) \* (**XN** - **X**floor(**K**/2)+1). We try to get this cost for all other valid placements of the warehouse. 18 | 19 | So, for i = floor(**K**/2) + 1 to **N** - (**K**-floor(**K**/2)) - 1, we check if Vi is more than the maximum element of our heap. If it is then we remove the maximum and insert Vi and update the sum of all our heap elements by subtracting the difference of the removed element and the inserted element. We subtract floor(**K**/2) \* (**XN** - **Xi+1**) from the sum and compare it with the minimum cost obtained thus far, updating it with the current cost if current cost is lower. 20 | 21 | We can use a similar approach to get the cost of all elements to the right, there Vi will just be **Xi** and we should iterate from right to left and in each iteration, subtract (**K**-floor(**K**/2)) \* **Xi** from the sum of the elements in the heap and update the minimum cost with that. 22 | 23 | Finally we see for which point i, the sum of cost of placing floor(**K**/2) stalls on the left of it, **K**-floor(**K**/2) stalls on the right and **Ci** is minimised and output this value. 24 | -------------------------------------------------------------------------------- /Round H/Diagonal Puzzle/README.md: -------------------------------------------------------------------------------- 1 | # Diagonal Puzzle 2 | 3 | ## Solution code 4 | 5 | See [solution source code js](/Round%20H/Diagonal%20Puzzle/solution.js) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20H/Diagonal%20Puzzle/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Kibur has made a new puzzle for you to solve! The puzzle consists of an **N** by **N** grid of squares. Each square is either black or white. The goal of the puzzle is to make all the squares black in as few moves as possible. 14 | 15 | In a single move, you may choose any diagonal of squares and flip the color of every square on that diagonal (black becomes white and white becomes black). For example, the 10 possible diagonals for a 3 by 3 grid are shown below. 16 | 17 | ``` 18 | /.. ./. ../ ... ... 19 | ... /.. ./. ../ ... 20 | ... ... /.. ./. ../ 21 | 22 | 23 | ... ... \.. .\. ..\ 24 | ... \.. .\. ..\ ... 25 | \.. .\. ..\ ... ... 26 | ``` 27 | 28 | Given the initial configuration of the board, what is the fewest moves needed to make all the squares black? You are guaranteed that it is possible to make all the squares black. 29 | 30 | ## Input 31 | 32 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case begins with a line containing the integer **N**, the size of the grid. Then, **N** lines follow, each containing **N** characters that describe the initial configuration of the grid. The c-th character on the r-th line is the character `.` (ASCII number 46) if the square in the r-th row and c-th column is initially white. Otherwise, it is # (ASCII number 35), indicating that it is black. 33 | 34 | ## Output 35 | 36 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the fewest moves needed to make all the squares black. 37 | 38 | ## Limits 39 | 40 | Time limit: 20 seconds per test set.
41 | Memory limit: 1GB.
42 | 1 ≤ **T** ≤ 100.
43 | You are guaranteed that it is possible to make all the squares black. 44 | 45 | ### Test set 1 (Visible) 46 | 47 | 2 ≤ **N** ≤ 8. 48 | 49 | ### Test set 2 (Hidden) 50 | 51 | 2 ≤ **N** ≤ 100. 52 | 53 | ## Sample 54 | 55 | | Input | Output | 56 | | ----- | ---------- | 57 | | 3 | | 58 | | 3 | Case #1: 3 | 59 | | ..# | | 60 | | #.# | | 61 | | #.. | | 62 | | 5 | Case #2: 2 | 63 | | .#### | | 64 | | #.### | | 65 | | ##.## | | 66 | | ###.# | | 67 | | ##### | | 68 | | 2 | Case #3: 0 | 69 | | ## | | 70 | | ## | | 71 | 72 | In sample case #1, the fewest moves needed is 3, as shown below: 73 | 74 |
75 | ..#    ..#    .##    ###
76 | #.# -> ..# -> #.# -> ###
77 | #..    ##.    ##.    ###
78 | 
79 | 80 | In sample case #2, the fewest moves needed is 2, as shown below: 81 | 82 |
83 | .####    #####    #####
84 | #.###    #####    #####
85 | ##.## -> ##### -> #####
86 | ###.#    #####    #####
87 | #####    ####.    #####
88 | 
89 | 90 | In sample case #3, all the squares in the grid are already black, so the answer is 0. 91 | -------------------------------------------------------------------------------- /Round B/Building Palindromes/README.md: -------------------------------------------------------------------------------- 1 | # Building Palindromes 2 | 3 | ## Solution code 4 | 5 | See [solution source code](/Round%20B/Building%20Palindromes/solution.js) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20B/Building%20Palindromes/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Anna has a row of **N** blocks, each with exactly one letter from A to Z written on it. The blocks are numbered 1, 2, ..., **N** from left to right. 14 | 15 | Today, she is learning about palindromes. A palindrome is a string that is the same written forwards and backwards. For example, `ANNA`, `RACECAR`, `AAA` and `X` are all palindromes, while `AB`, `FROG` and `YOYO` are not. 16 | 17 | Bob wants to test how well Anna understands palindromes, and will ask her **Q** questions. The i-th question is: can Anna use all of the blocks numbered from **Li** to **Ri**, inclusive, rearranging them if necessary, to form a palindrome? After each question, Anna puts the blocks back in their original positions. 18 | 19 | Please help Anna by finding out how many of Bob's questions she can answer "yes" to. 20 | 21 | ## Input 22 | 23 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case starts with a line containing the two integers **N** and **Q**, the number of blocks and the number of questions, respectively. Then, another line follows, containing a string of **N** uppercase characters (A to Z). Then, **Q** lines follow. The i-th line contains the two integers **Li** to **Ri**, describing the i-th question. 24 | 25 | ## Output 26 | 27 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the number of questions Anna can answer "yes" to. 28 | 29 | ## Limits 30 | 31 | Time limit: 30 seconds per test set.
32 | Memory limit: 1GB.
33 | 1 ≤ **T** ≤ 100. 1 ≤ **Li** ≤ **Ri** ≤ **N**. 34 | 35 | ### Test set 1 (Visible) 36 | 37 | 1 ≤ **N** ≤ 20.
38 | 1 ≤ **Q** ≤ 20. 39 | 40 | ### Test set 2 (Hidden) 41 | 42 | 1 ≤ **N** ≤ 105.
43 | 1 ≤ **Q** ≤ 105. 44 | 45 | ## Sample 46 | 47 | | Input | Output | 48 | | ------- | ---------- | 49 | | 2 | | 50 | | 7 5 | Case #1: 3 | 51 | | ABAACCA | | 52 | | 3 6 | | 53 | | 4 4 | | 54 | | 2 5 | | 55 | | 6 7 | | 56 | | 3 7 | | 57 | | 3 5 | Case #2: 0 | 58 | | XYZ | | 59 | | 1 3 | | 60 | | 1 3 | | 61 | | 1 3 | | 62 | | 1 3 | | 63 | | 1 3 | | 64 | 65 | In Sample Case #1, **N** = 7 and **Q** = 5. 66 | 67 | - For the first question, Anna must use the blocks `AACC`. She can rearrange these blocks into the palindrome `ACCA` (or `CAAC`). 68 | - For the second question, Anna must use the blocks A. This is already a palindrome, so she does not need to rearrange them. 69 | - For the third question, Anna must use the blocks `BAAC`. These blocks cannot be rearranged into a palindrome. 70 | - For the fourth question, Anna must use the blocks `CA`. These blocks cannot be rearranged into a palindrome. 71 | - For the fifth question, Anna must use the blocks `AACCA`. She can rearrange these blocks to form the palindrome `ACACA` (or `CAAAC`). 72 | 73 | In total, she is able to answer "yes" to 3 of Bob's questions, so the answer is 3. 74 | 75 | In Sample Case #2, **N** = 3 and **Q** = 5. For the first question, Anna must use the blocks `XYZ` to create a palindrome. This is impossible, and since the rest of Bob's questions are the same as the first one, the answer is 0. 76 | -------------------------------------------------------------------------------- /Practice Round/Mural/README.md: -------------------------------------------------------------------------------- 1 | # Mural 2 | 3 | ## Solution code 4 | 5 | See [solution source code](/Practice%20Round/Mural/solution.js) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Practice%20Round/Mural/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Thanh wants to paint a wonderful mural on a wall that is **N** sections long. Each section of the wall has a _beauty score_, which indicates how beautiful it will look if it is painted. Unfortunately, the wall is starting to crumble due to a recent flood, so he will need to work fast! 14 | 15 | At the beginning of each day, Thanh will paint one of the sections of the wall. On the first day, he is free to paint any section he likes. On each subsequent day, he must paint a new section that is next to a section he has already painted, since he does not want to split up the mural. 16 | 17 | At the end of each day, one section of the wall will be destroyed. It is always a section of wall that is adjacent to only one other section and is unpainted (Thanh is using a waterproof paint, so painted sections can't be destroyed). 18 | 19 | The _total beauty_ of Thanh's mural will be equal to the sum of the beauty scores of the sections he has painted. Thanh would like to guarantee that, no matter how the wall is destroyed, he can still achieve a total beauty of at least B. What's the maximum value of B for which he can make this guarantee? 20 | 21 | ## Input 22 | 23 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case starts with a line containing an integer **N**. Then, another line follows containing a string of **N** digits from 0 to 9. The i-th digit represents the beauty score of the i-th section of the wall. 24 | 25 | ## Output 26 | 27 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the maximum beauty score that Thanh can guarantee that he can achieve, as described above. 28 | 29 | ## Limits 30 | 31 | 1 ≤ **T** ≤ 100.
32 | Time limit: 20 seconds per test set.
33 | Memory limit: 1 GB.
34 | 35 | ### Small dataset (Test set 1 - Visible) 36 | 37 | 2 ≤ **N** ≤ 100. 38 | 39 | ### Large dataset (Test set 2 - Hidden) 40 | 41 | For exactly 1 case, **N** = 5 × 106; for the other **T** - 1 cases, 2 ≤ **N **≤ 100. 42 | 43 | ## Sample 44 | 45 | | Input | Output | 46 | | ---------- | ----------- | 47 | | 4 | | 48 | | 4 | Case #1: 6 | 49 | | 1332 | | 50 | | 4 | Case #2: 14 | 51 | | 9583 | | 52 | | 3 | Case #3: 7 | 53 | | 616 | | 54 | | 10 | Case #4: 31 | 55 | | 1029384756 | | 56 | 57 | In the first sample case, Thanh can get a total beauty of 6, no matter how the wall is destroyed. On the first day, he can paint either section of wall with beauty score 3. At the end of the day, either the 1st section or the 4th section will be destroyed, but it does not matter which one. On the second day, he can paint the other section with beauty score 3. 58 | 59 | In the second sample case, Thanh can get a total beauty of 14, by painting the leftmost section of wall (with beauty score 9). The only section of wall that can be destroyed is the rightmost one, since the leftmost one is painted. On the second day, he can paint the second leftmost section with beauty score 5. Then the last unpainted section of wall on the right is destroyed. Note that on the second day, Thanh cannot choose to paint the third section of wall (with beauty score 8), since it is not adjacent to any other painted sections. 60 | 61 | In the third sample case, Thanh can get a total beauty of 7. He begins by painting the section in the middle (with beauty score 1). Whichever section is destroyed at the end of the day, he can paint the remaining wall at the start of the second day. 62 | -------------------------------------------------------------------------------- /Round F/Teach Me/README.md: -------------------------------------------------------------------------------- 1 | # Teach Me 2 | 3 | ## Solution code 4 | 5 | See [solution source code js](/Round%20F/Teach%20Me/solution.js) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20F/Teach%20Me/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Here at Google we love teaching new skills to each other! There are **N** employees at Google, numbered from 1 to **N**. There are a total of **S** different skills, numbered from 1 to **S**. Each employee knows up to 5 different skills. 14 | 15 | The i-th employee can _mentor_ the j-th employee if there is a skill that the i-th employee knows that the j-th employee does not know. How many ordered pairs (i, j) are there where the i-th employee can mentor the j-th employee? 16 | 17 | ## Input 18 | 19 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. The first line of each test case gives the two integers **N** and **S**, which are the number of employees and the number of skills respectively. 20 | 21 | The next **N** lines describe the skills that each employee knows. The i-th of these lines begins with an integer **Ci** which is the number of skills the i-th employee knows. Then, **Ci** integers follow on the same line. The j-th of these integers is **Aij** indicating that the i-th employee knows the skill **Aij**. 22 | 23 | ## Output 24 | 25 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the number of ordered pairs (i, j) where the i-th employee can mentor the j-th employee. 26 | 27 | ## Limits 28 | 29 | Time limit: 40 seconds per test set.
30 | Memory limit: 1GB.
31 | 1 ≤ **T** ≤ 100.
32 | 1 ≤ **S** ≤ 1000.
33 | 1 ≤ **Ci** ≤ 5 for all i.
34 | 1 ≤ **Aij** ≤ **S** for all i and j.
35 | **Aij** ≠ **Aik** for all j ≠ k. 36 | 37 | ### Test set 1 (Visible) 38 | 39 | 2 ≤ **N** ≤ 500. 40 | 41 | ### Test set 2 (Hidden) 42 | 43 | 2 ≤ **N** ≤ 5 × 104. 44 | 45 | ## Sample 46 | 47 | | Input | Output | 48 | | ---------------- | ---------- | 49 | | 2 | | 50 | | 4 100 | Case #1: 7 | 51 | | 4 80 90 100 5 | | 52 | | 1 90 | | 53 | | 1 80 | | 54 | | 3 80 90 100 | | 55 | | 3 30 | Case #2: 4 | 56 | | 4 10 11 12 13 | | 57 | | 4 10 11 12 13 | | 58 | | 5 25 26 27 28 29 | | 59 | 60 | In Sample case #1: 61 | 62 | - (1, 2) is a valid pair since employee 1 knows the skill 100 (also 5 and 80), while employee 2 does not. 63 | - (1, 3) is a valid pair since employee 1 knows the skill 100 (also 5 and 90), while employee 3 does not. 64 | - (1, 4) is a valid pair since employee 1 knows the skill 5, while employee 4 does not. 65 | - (2, 3) is a valid pair since employee 2 knows the skill 90, while employee 3 does not. 66 | - (3, 2) is a valid pair since employee 3 knows the skill 80, while employee 2 does not. 67 | - (4, 2) is a valid pair since employee 4 knows the skill 100 (also 80), while employee 2 does not. 68 | - (4, 3) is a valid pair since employee 4 knows the skill 100 (also 90), while employee 3 does not. 69 | 70 | In total, there are 7 valid pairs, so the answer is 7. 71 | 72 | In Sample case #2: 73 | 74 | - (1, 3) is a valid pair since employee 1 knows the skill 10 (also 11, 12 and 13), while employee 3 does not. 75 | - (2, 3) is a valid pair since employee 2 knows the skill 10 (also 11, 12 and 13), while employee 3 does not. 76 | - (3, 1) is a valid pair since employee 3 knows the skill 28 (also 25, 26, 27 and 29), while employee 1 does not. 77 | - (3, 2) is a valid pair since employee 3 knows the skill 27 (also 25, 26, 28 and 29), while employee 2 does not. 78 | 79 | In total, there are 4 valid pairs, so the answer is 4. 80 | -------------------------------------------------------------------------------- /Round F/Flattening/README.md: -------------------------------------------------------------------------------- 1 | # Flattening 2 | 3 | ## Solution code 4 | 5 | See [solution source code js](/Round%20F/Flattening/solution.js) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20F/Flattening/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Blotch has built a wall. The wall is made up of **N** sections, numbered from 1 to **N** from left to right. Since he had built the wall in a hurry, not all the sections are of the same height. The i-th section of wall is **Ai** metres tall. 14 | 15 | Blotch would like to fix his wall by rebuilding some of the sections. Blotch can set the height of each section he rebuilds to any height he chooses. 16 | 17 | Blotch will be _happy_ if the number of indices i (1 ≤ i < **N**) where **Ai** ≠ **Ai+1** is not more than **K**. 18 | 19 | What is the fewest sections of the wall Blotch needs to rebuild so that he will be happy? 20 | 21 | ## Input 22 | 23 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case begins with a line containing the two integers **N** and **K**, the number of sections of wall and the maximum number of changes in height between adjacent sections, respectively. 24 | 25 | The second line contains **N** integers. The i-th integer is **Ai**, the height of the i-th section of wall. 26 | 27 | ## Output 28 | 29 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the fewest sections that Blotch has to rebuild so that he will be happy. 30 | 31 | ## Limits 32 | 33 | Time limit: 15 seconds per test set.
34 | Memory limit: 1GB.
35 | 1 ≤ **T** ≤ 100.
36 | 1 ≤ **Ai** ≤ 1000, for all i.
37 | 0 ≤ **K** ≤ **N**. 38 | 39 | ### Test set 1 (Visible) 40 | 41 | 2 ≤ **N** ≤ 20. 42 | 43 | ### Test set 2 (Hidden) 44 | 45 | 2 ≤ **N** ≤ 100. 46 | 47 | ## Sample 48 | 49 | | Input | Output | 50 | | ------------------------------- | ---------- | 51 | | 4 | | 52 | | 8 2 | Case #1: 3 | 53 | | 300 100 300 300 200 100 800 500 | | 54 | | 5 3 | Case #2: 0 | 55 | | 100 100 100 100 3 | | 56 | | 7 3 | Case #3: 1 | 57 | | 10 20 40 10 10 30 30 | | 58 | | 10 2 | Case #4: 2 | 59 | | 30 30 60 60 90 90 60 60 30 30 | | 60 | 61 | In the first sample case, there are **N** = 8 sections of wall, and Blotch will be happy if there are at most **K** = 2 changes in height between adjacent sections. Blotch can: 62 | 63 | - rebuild the 2nd section of wall to have height 300, 64 | - rebuild the 6th section of wall to have height 200, and 65 | - rebuild the 8th section of wall to have height 800. 66 | 67 | This produces a wall with sections of height 300, 300, 300, 300, 200, 200, 800 and 800, which makes Blotch happy. 68 | 69 | In the second sample case, there are **N** = 5 sections of wall, and Blotch will be happy if there are at most **K** = 3 changes in height between adjacent sections. Blotch is already happy with this wall, so he does not need to rebuild any sections. 70 | 71 | In the third sample case, there are **N** = 7 sections of wall, and Blotch will be happy if there are at most **K** = 3 changes in height between adjacent sections. Blotch can: 72 | 73 | - rebuild the 2nd section of wall to have height 10. 74 | 75 | This produces a wall with sections of height 10, 10, 40, 10, 10, 30 and 30 which makes Blotch happy. 76 | 77 | In the fourth sample case, there are **N** = 10 sections of wall, and Blotch will be happy if there are at most **K** = 2 changes in height between adjacent sections. Blotch can: 78 | 79 | - rebuild the 5th section of wall to have height 60, and 80 | - rebuild the 6th section of wall to have height 60. 81 | 82 | This produces a wall with sections of height 30, 30, 60, 60, 60, 60, 60, 60, 30, 30 which makes Blotch happy. 83 | -------------------------------------------------------------------------------- /Round D/Food Stalls/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | int main() 12 | { 13 | /* 14 | Limits: 15 | Time limit: 16 | 30 seconds per test set. 17 | Memory limit: 18 | 1GB. 19 | Vars 20 | 1 ≤ T ≤ 100. 21 | 1 ≤ K < N 22 | 1 ≤ Ci ≤ 10^9, for all i. 23 | 1 ≤ Xi ≤ 10^9, for all i. 24 | Xi ≠ Xj for all i ≠ j. 25 | 26 | Test set 1 (Visible) 27 | 2 ≤ N ≤ 100 28 | 29 | Test set 2 (Hidden) 30 | There will be at most 5 cases with 500 < N ≤ 10^5. 31 | The remaining cases will have 2 ≤ N ≤ 500 32 | */ 33 | 34 | int T; 35 | long long K, N; 36 | priority_queue heap; 37 | long long spots[100001]; 38 | long long sortedSpotIndex[100001]; 39 | long long buildCosts[100001]; 40 | long long leftCosts[100001]; 41 | long long rightCosts[100001]; 42 | long long heapSum, lastSpot, mid, minTmpCost, min; 43 | cin >> T; 44 | 45 | for (int t = 0; t < T; t++) 46 | { 47 | cin >> K >> N; 48 | heap = priority_queue(); 49 | lastSpot = 0LL; 50 | minTmpCost = LLONG_MAX; 51 | min = LLONG_MAX; 52 | 53 | for (int i = 0; i < N; i++) 54 | { 55 | cin >> spots[i]; 56 | sortedSpotIndex[i] = i; 57 | leftCosts[i] = LLONG_MAX; 58 | rightCosts[i] = LLONG_MAX; 59 | if (spots[i] > lastSpot) 60 | { 61 | lastSpot = spots[i]; 62 | } 63 | } 64 | for (int i = 0; i < N; i++) 65 | { 66 | cin >> buildCosts[i]; 67 | } 68 | sort(sortedSpotIndex, sortedSpotIndex + N, [&spots](int a, int b) { return spots[a] < spots[b]; }); 69 | heapSum = 0LL; 70 | mid = K / 2LL; 71 | for (int i = 0; i < mid; i++) 72 | { 73 | int id = sortedSpotIndex[i]; 74 | long long vi = lastSpot - spots[id] + buildCosts[id]; 75 | heap.push(vi); 76 | heapSum += vi; 77 | } 78 | minTmpCost = heapSum - mid * (lastSpot - spots[sortedSpotIndex[mid]]); 79 | leftCosts[mid] = minTmpCost; 80 | for (int i = mid; i < N - (K - mid) - 1; i++) 81 | { 82 | if (heap.empty()) 83 | { 84 | leftCosts[i + 1] = minTmpCost; 85 | continue; 86 | } 87 | int id = sortedSpotIndex[i]; 88 | long long vi = lastSpot - spots[id] + buildCosts[id]; 89 | long long top = heap.top(); 90 | if (vi < top) 91 | { 92 | heap.pop(); 93 | heap.push(vi); 94 | heapSum -= top; 95 | heapSum += vi; 96 | } 97 | leftCosts[i + 1] = heapSum - mid * (lastSpot - spots[sortedSpotIndex[i + 1]]); 98 | } 99 | 100 | heap = priority_queue(); 101 | heapSum = 0; 102 | for (int i = N - 1; i >= N - (K - mid); i--) 103 | { 104 | int id = sortedSpotIndex[i]; 105 | long long vi = spots[id] + buildCosts[id]; 106 | heap.push(vi); 107 | heapSum += vi; 108 | } 109 | minTmpCost = heapSum - spots[sortedSpotIndex[N - (K - mid) - 1]] * (K - mid); 110 | rightCosts[N - (K - mid) - 1] = minTmpCost; 111 | for (int i = N - (K - mid) - 1; i >= (K - mid); i--) 112 | { 113 | int id = sortedSpotIndex[i]; 114 | long long vi = spots[id] + buildCosts[id]; 115 | long long top = heap.top(); 116 | if (vi < top) 117 | { 118 | heap.pop(); 119 | heap.push(vi); 120 | heapSum -= top; 121 | heapSum += vi; 122 | } 123 | rightCosts[i - 1] = heapSum - spots[sortedSpotIndex[i - 1]] * (K - mid); 124 | } 125 | 126 | for (int i = mid; i < N - (K - mid); i++) 127 | { 128 | if (leftCosts[i] + rightCosts[i] + buildCosts[sortedSpotIndex[i]] < min) 129 | { 130 | min = leftCosts[i] + rightCosts[i] + buildCosts[sortedSpotIndex[i]]; 131 | } 132 | } 133 | cout << "Case #" << t + 1 << ": " << min << endl; 134 | } 135 | 136 | return 0; 137 | } -------------------------------------------------------------------------------- /Round F/Spectating Villages/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', (inputStdin) => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', (_) => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map((str) => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | let dp; 23 | let mb; 24 | function solution() { 25 | const T = Number(readLine()); 26 | for (let t = 0; t < T; t++) { 27 | const V = Number(readLine()); 28 | let beauty = readLine().split(' ').map(Number); 29 | let roads = Array(V) 30 | .fill(null) 31 | .map(() => []); 32 | 33 | for (let i = 0; i < V - 1; i++) { 34 | let [x, y] = readLine().split(' ').map(Number); 35 | x--; 36 | y--; 37 | roads[x].push(y); 38 | roads[y].push(x); 39 | } 40 | removeParents(roads, 0, -1); 41 | 42 | mb = Array(V) 43 | .fill(null) 44 | .map(() => 45 | Array(2) 46 | .fill(null) 47 | .map(() => Array(2).fill(-1)) 48 | ); 49 | dp = Array(V) 50 | .fill(null) 51 | .map((_, j) => 52 | Array(roads[j].length + 1) 53 | .fill(null) 54 | .map(() => Array(2).fill(-1)) 55 | ); 56 | 57 | for (let i = 0; i < V; i++) { 58 | dp[i][0][0] = 0; 59 | dp[i][0][1] = 0; 60 | } 61 | const a = maxBeauty(roads, beauty, 0, 0, 0); 62 | const b = maxBeauty(roads, beauty, 0, 0, 1); 63 | console.log(`Case #${t + 1}: ${Math.max(a, b)}`); 64 | } 65 | } 66 | function removeParents(roads, node, parent) { 67 | if (parent != -1) { 68 | let i = roads[node].findIndex((c) => c === parent); 69 | if (i >= 0) { 70 | roads[node].splice(i, 1); 71 | } 72 | } 73 | for (let n of roads[node]) { 74 | removeParents(roads, n, node); 75 | } 76 | } 77 | 78 | function maxBeauty(roads, beauty, node, parentOn, on) { 79 | if (mb[node][parentOn][on] == -1) { 80 | let ans = 0; 81 | if (on) { 82 | ans += beauty[node]; 83 | for (let c of roads[node]) { 84 | ans += Math.max(maxBeauty(roads, beauty, c, on, 1), maxBeauty(roads, beauty, c, on, 0)); 85 | } 86 | } else { 87 | if (parentOn) { 88 | ans += beauty[node]; 89 | for (let c of roads[node]) { 90 | ans += Math.max(maxBeauty(roads, beauty, c, on, 0), maxBeauty(roads, beauty, c, on, 1)); 91 | } 92 | } else { 93 | if (dp[node][roads[node].length][0] == -1) { 94 | computeDinamic(roads, beauty, node, roads[node].length, 0); 95 | } 96 | if (dp[node][roads[node].length][1] == -1) { 97 | computeDinamic(roads, beauty, node, roads[node].length, 1); 98 | } 99 | let a = dp[node][roads[node].length][0]; 100 | if (roads[node].length > 0) { 101 | a = beauty[node] + dp[node][roads[node].length][1]; 102 | } 103 | ans += Math.max(a, dp[node][roads[node].length][0]); 104 | } 105 | } 106 | mb[node][parentOn][on] = ans; 107 | } 108 | return mb[node][parentOn][on]; 109 | } 110 | 111 | function computeDinamic(roads, beauty, node, child, on) { 112 | if (dp[node][child - 1][on] == -1) { 113 | computeDinamic(roads, beauty, node, child - 1, on); 114 | } 115 | 116 | if (on) { 117 | let a = maxBeauty(roads, beauty, roads[node][child - 1], 0, 0); 118 | if (child == 1) { 119 | a = maxBeauty(roads, beauty, roads[node][child - 1], 0, 1); 120 | } 121 | dp[node][child][1] = Math.max( 122 | dp[node][child - 1][1] + Math.max(a, maxBeauty(roads, beauty, roads[node][child - 1], 0, 1)), 123 | dp[node][child - 1][0] + maxBeauty(roads, beauty, roads[node][child - 1], 0, 1) 124 | ); 125 | } else { 126 | dp[node][child][0] = 127 | dp[node][child - 1][0] + maxBeauty(roads, beauty, roads[node][child - 1], 0, 0); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /Round C/Circuit Board/analysis.md: -------------------------------------------------------------------------------- 1 | # Analysis 2 | 3 | ## Test set 1 (Visible) 4 | 5 | Restating the problem, we are asked to find the largest sub-rectangle in a grid of integers such that the difference between the maximum and minimum integers in each row of the sub-rectangle is not more than **K**. 6 | 7 | For test set 1, we have **K** = 0. This means we have to find the largest sub-rectangle in which all integers are equal in each of the rows. 8 | 9 | To do this, we first define Pi,j as the maximum number of contigious cells on the right of the cell i, j which have the same value as cell i, j. 10 | 11 | We immediately observe that Pi, j = 1 + Pi, j + 1 if the integers in j and (j+1)th columns of row i are equal, else Pi,j is 1. 12 | 13 | Once we have these values, our problem simply reduces to the well known problem of finding the area of the largest rectangle in a histogram. For every column c, we first divide it into segments where all integers are equal. For any such segment say from row r1 to r2, we take Pi, c for i = r1 to r2 as the heights of histogram. It is clear now that any rectangle in this histogram represents a rectangle where in all integers are equal in each row of the rectangle. 14 | 15 | Calculating the largest rectangle in the histogram of width M can be done in O(M) time using stacks. The idea is to find for every bar of the histogram, the closest bars to the left and right of the current bar which are shorter than the current bar. To find the closest shorter bar on the left (we can modify the same procedure to also find the closest shorter bar on the right), we traverse our histogram from left to right. We initially have an empty stack which we update as follows:
16 | If the current bar's height is greater than the top element of the stack, then it's the required bar for our current bar and we push the current bar's height into the stack.
17 | Otherwise we keep on popping the stack till we find a number which is lesser than the current bar's height (or the stack becomes empty, in which case there's no bar to the left which is shorter than the current bar). This top element now corresponds to our required bar. We then push the current bar's height into our stack. Since we push or pop at most once for every bar, the complexity of this procedure is linear as described above. 18 | 19 | And hence, we'll have to spend O(**R**) time per column with a total run time complexity of O(**RC**). 20 | 21 | ## Test set 2 (Hidden) 22 | 23 | For this case, **K** >= 0, so we re-define Pi,j as the maximum length such that the difference between the maximum number and the minimum number present in all cells of row i with column >= j and < j + Pi,j is not more than **K**. 24 | 25 | To calculate Pi,j we binary search for the first cell in the ith row and to the right of jth column such that the condition that the difference between the maximum and minimum number present in these cells is not more than **K** is violated. We can do this quickly if we can answer range minimum and range maximum queries quickly. Those can be dealt with a lot of different data-structures. 26 | 27 | Once we have this, our problem again reduces to the problem of finding the area of the largest rectangle in a histogram. For, every column c, we take Pi, c for `i = 1` to **R** as the heights of histogram. It is clear now that any rectangle in this histogram represents a rectangle where in no row maximum and minimum elements differ by more than **K**. 28 | 29 | If we use a data-structure like Sparse Table to answer the range minimum and maximum queries then we can find all the P-values in O(**RC**log(**C**)) time. The last part of finding the largest area rectangle in histogram should be done once for each column, and hence takes O(**R**) time for each case resulting in O(**RC**) time in total. Combining both, we have a final complexity of O(**RC**log(**C**)). We can further reduce this to a complexity of O(**RC**) by replacing the Sparse Table data-structure with a two pointers variation using two deques, that approach is left as an exercise for the reader. 30 | -------------------------------------------------------------------------------- /Round B/Diverse Subarray/README.md: -------------------------------------------------------------------------------- 1 | # Diverse Subarray 2 | 3 | ## Solution code 4 | 5 | See [solution source code c++](/Round%20B/Diverse%20Subarray/solution.cpp) 6 | 7 | See [solution source code js](/Round%20B/Diverse%20Subarray/solution.js) 8 | 9 | ## Analysis 10 | 11 | You can see [solution analysis](/Round%20B/Diverse%20Subarray/analysis.md) extracted from Google webpage. 12 | 13 | ## Problem 14 | 15 | Vanity has **N** trinkets on her shelf, numbered 1, 2, ..., **N** from left to right. Trinkets come in different types, which are denoted by positive integers. The i-th trinket on her shelf is of type **Ai**. 16 | 17 | She is going to see her family overseas today and would like to bring as many trinkets as she can. However, since she is in a hurry, Vanity must take a consecutive interval of trinkets. Formally, Vanity selects two indices, l and r, and takes all of the trinkets numbered _l_, _l_+1, ..., _r_-1, _r_. Also, due to tax rules, airport security will throw away _all_ trinkets of a type if Vanity has more than **S** of that type in the chosen interval. 18 | 19 | For example, suppose that **S** = 2, and Vanity brings six trinkets: one of type 0, two of type 1, and three of type 2. She will be allowed to keep the trinket of type 0 and both trinkets of type 1, but she will lose _all_ of the trinkets of type 2! 20 | 21 | Vanity needs to choose _l_ and _r_ such that she can take the maximum number of trinkets for her family. What is the maximum number of trinkets she can bring? 22 | 23 | ## Input 24 | 25 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. The first line of each test case contains the two integers **N** and **S**, the number of trinkets, and the maximum number of trinkets allowed of a single type, respectively. The second line contains **N** integers. The i-th integer gives **Ai**, the type of the i-th trinket. 26 | 27 | ## Output 28 | 29 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the maximum number of trinkets that Vanity can bring to her family. 30 | 31 | ## Limits 32 | 33 | Time limit: 30 seconds per test set.
34 | Memory limit: 1GB.
35 | 1 ≤ **T** ≤ 100.
36 | 1 ≤ **Ai** ≤ 105.
37 | 1 ≤ **S** ≤ **N**. 38 | 39 | ### Test set 1 (Visible) 40 | 41 | 1 ≤ **N** ≤ 1000. 42 | 43 | ### Test set 2 (Hidden) 44 | 45 | 1 ≤ **N** ≤ 105. 46 | 47 | ## Sample 48 | 49 | | Input | Output | 50 | | ----------------------------- | ---------- | 51 | | 4 | | 52 | | 6 2 | Case #1: 4 | 53 | | 1 1 4 1 4 4 | | 54 | | 8 1 | Case #2: 6 | 55 | | 1 2 500 3 4 500 6 7 | | 56 | | 10 1 | Case #3: 4 | 57 | | 100 200 8 8 8 8 8 300 400 100 | | 58 | | 12 2 | Case #4: 6 | 59 | | 40 50 1 1 1 60 70 2 2 2 80 90 | | 60 | 61 | In Sample Case #1, Vanity should choose _l_ = 2 and _r_ = 5. This allows her to take 4 trinkets to the airport of types 1, 4, 1 and 4. None of them are thrown away by airport security, so she is able to bring 4 trinkets to her family. 62 | 63 | In Sample Case #2, Vanity should choose _l_ = 1 and _r_ = 8. This allows her to take all 8 trinkets to the airport. Her trinkets of type 500 are thrown away since she has more than **S** = 1 of them, so she is able to bring a total of 6 trinkets to her family. 64 | 65 | In Sample Case #3, Vanity should choose l = 1 and r = 9. This allows her to take 9 trinkets to the airport of types 100, 200, 8, 8, 8, 8, 8, 300 and 400. Her trinkets of type 8 are thrown away since she has more than S = 1 of them, so she is able to bring a total of 4 trinkets to her family. 66 | 67 | In Sample Case #4, Vanity should choose _l_ = 1 and _r_ = 12. This allows her to take all 12 trinkets to the airport. Her trinkets of type 1 and 2 are thrown away since she has more than **S** = 2 of each of them, so she is able to bring a total of 6 trinkets to her family. 68 | 69 | **Note**: We do not recommend using interpreted/slower languages for this problem. 70 | -------------------------------------------------------------------------------- /Round F/Spectating Villages/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | long long maxBeauty(long long node, long long parentOn, long long on); 11 | 12 | long long beauty[100001]; 13 | vector roads[100001]; 14 | long long mb[100001][2][2]; 15 | vector> dp[100001]; 16 | 17 | void removeParents(long long node, long long parent) 18 | { 19 | if (parent != -1) 20 | { 21 | roads[node].erase(remove(roads[node].begin(), roads[node].end(), parent), roads[node].end()); 22 | } 23 | for (auto it = roads[node].begin(); it != roads[node].end(); it++) 24 | { 25 | removeParents(*it, node); 26 | } 27 | } 28 | 29 | void computeDinamic(long long node, long long child, long long on) 30 | { 31 | 32 | if (dp[node][child - 1][on] == -1) 33 | { 34 | computeDinamic(node, child - 1, on); 35 | } 36 | 37 | if (on) 38 | { 39 | long long a = maxBeauty(roads[node][child - 1], 0, 0); 40 | if (child == 1) 41 | { 42 | a = maxBeauty(roads[node][child - 1], 0, 1); 43 | } 44 | dp[node][child][1] = max( 45 | dp[node][child - 1][1] + max(a, maxBeauty(roads[node][child - 1], 0, 1)), 46 | dp[node][child - 1][0] + maxBeauty(roads[node][child - 1], 0, 1)); 47 | } 48 | else 49 | { 50 | dp[node][child][0] = 51 | dp[node][child - 1][0] + maxBeauty(roads[node][child - 1], 0, 0); 52 | } 53 | } 54 | 55 | long long maxBeauty(long long node, long long parentOn, long long on) 56 | { 57 | if (mb[node][parentOn][on] == -1) 58 | { 59 | long long ans = 0; 60 | if (on) 61 | { 62 | ans += beauty[node]; 63 | for (auto it = roads[node].begin(); it != roads[node].end(); it++) 64 | { 65 | ans += max(maxBeauty(*it, on, 1), maxBeauty(*it, on, 0)); 66 | } 67 | } 68 | else 69 | { 70 | if (parentOn) 71 | { 72 | ans += beauty[node]; 73 | for (auto it = roads[node].begin(); it != roads[node].end(); it++) 74 | { 75 | ans += max(maxBeauty(*it, on, 0), maxBeauty(*it, on, 1)); 76 | } 77 | } 78 | else 79 | { 80 | if (dp[node][roads[node].size()][0] == -1) 81 | { 82 | computeDinamic(node, roads[node].size(), 0); 83 | } 84 | if (dp[node][roads[node].size()][1] == -1) 85 | { 86 | computeDinamic(node, roads[node].size(), 1); 87 | } 88 | long long a = dp[node][roads[node].size()][0]; 89 | if (roads[node].size() > 0) 90 | { 91 | a = beauty[node] + dp[node][roads[node].size()][1]; 92 | } 93 | ans += max(a, dp[node][roads[node].size()][0]); 94 | } 95 | } 96 | mb[node][parentOn][on] = ans; 97 | } 98 | return mb[node][parentOn][on]; 99 | } 100 | 101 | int main() 102 | { 103 | long long T; 104 | long long V; 105 | long long x, y; 106 | 107 | cin >> T; 108 | 109 | for (long long t = 0; t < T; t++) 110 | { 111 | cin >> V; 112 | for (long long i = 0; i < V; i++) 113 | { 114 | cin >> beauty[i]; 115 | roads[i].clear(); 116 | mb[i][0][0] = -1; 117 | mb[i][0][1] = -1; 118 | mb[i][1][0] = -1; 119 | mb[i][1][1] = -1; 120 | 121 | dp[i].clear(); 122 | } 123 | for (long long i = 0; i < V - 1; i++) 124 | { 125 | cin >> x >> y; 126 | x--; 127 | y--; 128 | roads[x].push_back(y); 129 | roads[y].push_back(x); 130 | } 131 | removeParents(0, -1); 132 | 133 | for (long long i = 0; i < V; i++) 134 | { 135 | for (long long j = 0; j <= roads[i].size(); j++) 136 | { 137 | vector pb; 138 | pb.push_back(-1); 139 | pb.push_back(-1); 140 | dp[i].push_back(pb); 141 | } 142 | dp[i][0][0] = 0; 143 | dp[i][0][1] = 0; 144 | } 145 | long long a = maxBeauty(0, 0, 0); 146 | long long b = maxBeauty(0, 0, 1); 147 | cout << "Case #" << t + 1 << ": " << max(a, b) << endl; 148 | } 149 | 150 | return 0; 151 | } -------------------------------------------------------------------------------- /Round D/X or What?/README.md: -------------------------------------------------------------------------------- 1 | # X or What? 2 | 3 | ## Solution code 4 | 5 | See [solution source code c++](/Round%20D/X%20or%20What%3F/solution.cpp) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20D/X%20or%20What%3F/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Steven has an array of **N** non-negative integers. The i-th integer (indexed starting from 0) in the array is **Ai**. 14 | 15 | Steven really likes subintervals of **A** that are xor-even. Formally, a subinterval of **A** is a pair of indices (L, R), denoting the elements **AL**, **AL+1**, ..., **AR-1**, **AR**. The xor-sum of this subinterval is **AL** xor **AL+1** xor ... xor **AR-1** xor **AR**, where xor is the [bitwise exclusive or](https://en.wikipedia.org/wiki/Bitwise_operation#XOR). 16 | 17 | A subinterval is _xor-even_ if its xor-sum has an even number of set bits in its binary representation. 18 | 19 | Steven would like to make **Q** modifications to the array. The i-th modification changes the Pi-th (indexed from 0) element to **Vi**. Steven would like to know, what is the size of the xor-even subinterval of **A** with the most elements after each modification? 20 | 21 | ## Input 22 | 23 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. 24 | 25 | Each test case starts with a line containing two integers **N** and **Q**, denoting the number of elements in Steven's array and the number of modifications, respectively. 26 | 27 | The second line contains **N** integers. The i-th of them gives **Ai** indicating the i-th integer in Steven's array. 28 | 29 | Then, **Q** lines follow, describing the modifications. The i-th line contains **Pi** and **Vi**, The i-th modification changes the **Pi**-th element to **Vi**. indicating that the i-th modification changes the **Pi**-th (indexed from 0) element to **Vi**. 30 | 31 | ## Output 32 | 33 | For each test case, output one line containing Case #x: y1 y2 ... yQ, where `x` is the test case number (starting from 1) and yi is the number of elements in the largest xor-even subinterval of **A** after the i-th modification. If there are no xor-even subintervals, then output 0. 34 | 35 | ## Limits 36 | 37 | Time limit: 40 seconds per test set.
38 | Memory limit: 1GB.
39 | 1 ≤ **T** ≤ 100.
40 | 1 ≤ **Ai** < 1024.
41 | 0 ≤ **Pi** < **N**.
42 | 0 ≤ **Vi** < 1024. 43 | 44 | ### Test set 1 (Visible) 45 | 46 | 1 ≤ **N** ≤ 100.
47 | 1 ≤ **Q** ≤ 100. 48 | 49 | ### Test set 2 (Hidden) 50 | 51 | 1 ≤ **N** ≤ 105.
52 | 1 ≤ **Q** ≤ 105. 53 | 54 | ## Sample 55 | 56 | | Input | Output | 57 | | ------------- | -------------- | 58 | | 2 | | 59 | | 4 3 | Case #1: 4 3 4 | 60 | | 10 21 3 7 | | 61 | | 1 13 | | 62 | | 0 32 | | 63 | | 2 22 | | 64 | | 5 1 | Case #2: 4 | 65 | | 14 1 15 20 26 | | 66 | | 4 26 | | 67 | 68 | In Sample Case 1, **N** = 4 and **Q** = 3. 69 | 70 | - After the 1st modification, **A** is [10, 13, 3, 7]. The subinterval (0, 3) has xor-sum 10 xor 13 xor 3 xor 7 = 3. In binary, the xor-sum is 112, which has an even number of 1 bits, so the subinterval is xor-even. This is the largest subinterval possible, so the answer is 4. 71 | - After the 2nd modification, **A** is [32, 13, 3, 7]. The largest xor-even subinterval is (0, 2), which has xor-sum 32 xor 13 xor 3 = 46. In binary, this is 1011102. 72 | - After the 3rd modification, **A** is [32, 13, 22, 7]. The largest xor-even subinterval is (0, 3) again, which has xor-sum 32 xor 13 xor 22 xor 7 = 60. In binary, this is 1111002. 73 | 74 | In Sample Case 2, **N** = 5 and **Q** = 1. After the 1st modification, **A** is [14, 1, 15, 20, 26]. The largest xor-even subinterval is (1, 4), which has xor sum 1 xor 15 xor 20 xor 26 = 0. In binary, this is 02. 75 | -------------------------------------------------------------------------------- /Round D/Food Stalls/README.md: -------------------------------------------------------------------------------- 1 | # Food Stalls 2 | 3 | ## Solution code 4 | 5 | See [solution source code c++](/Round%20D/Food%20Stalls/solution.cpp) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20D/Food%20Stalls/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Everybody loves street food, especially the local residents of Bitetown! For this reason, you have decided to build exactly **K** food stalls and one warehouse on the main street of Bitetown. 14 | 15 | The main street is a long horizontal line that is 109 metres long. There are **N** spots that you are allowed to build stalls or a warehouse on. You may not build anywhere else on the street. The i-th spot is **Xi** meters from the left end of the street. 16 | 17 | You can build at most one stall or warehouse at the i-th spot (but not both), which costs **Ci** dollars. Additionally, if the warehouse is in the j-th spot, then building a stall in the i-th spot costs an extra |**Xj** - **Xi**| dollars. 18 | 19 | Please find the minimum cost to build exactly **K** food stalls and one warehouse. 20 | 21 | ## Input 22 | 23 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case starts with a line containing two integers **K** and **N**, the number of stalls you must build and the number of spots on the street, respectively. 24 | 25 | The second line contains **N** integers **Xi**; the i-th of these is the distance of the i-th spot from the left end of the street, in meters. 26 | 27 | The third line contains **N** integers **Ci**; the i-th of these is the cost of building a stall or warehouse at the i-th spot. 28 | 29 | ## Output 30 | 31 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and y is the minimum cost to build **K** stalls. 32 | 33 | ## Limits 34 | 35 | Time limit: 30 seconds per test set.
36 | Memory limit: 1GB.
37 | 1 ≤ **T** ≤ 100.
38 | 1 ≤ **K** < **N**.
39 | 1 ≤ **Ci** ≤ 109, for all i.
40 | 1 ≤ **Xi** ≤ 109, for all i.
41 | **Xi** ≠ **Xj** for all i ≠ j. 42 | 43 | ### Test set 1 (Visible) 44 | 45 | 2 ≤ **N** ≤ 100. 46 | 47 | ### Test set 2 (Hidden) 48 | 49 | There will be at most 5 cases with 500 < **N** ≤ 105.
50 | The remaining cases will have 2 ≤ **N** ≤ 500. 51 | 52 | ## Sample 53 | 54 | | Input | Output | 55 | | -------------------- | ------------ | 56 | | 3 | | 57 | | 2 4 | Case #1: 178 | 58 | | 1 2 3 10 | | 59 | | 100 70 80 20 | | 60 | | 1 5 | Case #1: 178 | 61 | | 150 300 301 400 700 | | 62 | | 8 35 26 5 2 | | 63 | | 6 7 | Case #1: 178 | 64 | | 22 21 20 23 26 25 24 | | 65 | | 10 10 10 10 10 10 10 | | 66 | 67 | In Sample Case 1, you must build **K** = 2 stalls and one warehouse, and there are **N** = 4 spots to build on. One possible solution is to build the warehouse on the 3rd spot with cost 80 dollars, and build the two stalls on the 2nd and 4th spot. 68 | 69 | - The stall on the 2nd spot costs 70 + |3 - 2| = 71 dollars. 70 | - The stall on the 4nd spot costs 20 + |3 - 10| = 27 dollars. 71 | 72 | This costs 178 dollars in total, which is the minimum possible, so the answer is 178. 73 | 74 | In Sample Case 2, you must build **K** = 1 stalls and one warehouse, and there are **N** = 5 spots to build on. One possible solution is to build the warehouse on the 2nd spot with cost 35 dollars, and build the stall on the 3rd spot, which costs 26 + |301-300| = 27 dollars. This costs 62 dollars in total, which is the minimum possible. 75 | 76 | In Sample Case 3, you must build **K** = 6 stalls and one warehouse, and there are **N** = 7 spots to build on. One possible solution is to build the warehouse on the 4th spot and build the 6 stalls on the 6 remaining spots. It is left as an exercise to the contestant to verify that this costs 82 dollars in total and is the minimum possible. Note that in this example, the spots are not in ascending order of their distance from the left end of the street. 77 | -------------------------------------------------------------------------------- /Round A/Contention/README.md: -------------------------------------------------------------------------------- 1 | # Contention 2 | 3 | ## Solution code 4 | 5 | See [solution source code c++](/Round%20A/Contention/solution.cpp) 6 | 7 | See [solution source code js](/Round%20A/Contention/solution.js) 8 | 9 | ## Analysis 10 | 11 | You can see [solution analysis](/Round%20A/Contention/analysis.md) extracted from Google webpage. 12 | 13 | ## Problem 14 | 15 | You are selling tickets for the front row of seats at a movie theater. The front row has **N** seats, numbered 1 to **N** from left to right. You have been out of the office the last week, and upon your return, **Q** bookings for seats have piled up! The i-th booking requests all the seats from **Li** to **Ri** inclusive. You now have the boring job of entering each booking into the system, one at a time. 16 | 17 | Since some of the bookings may overlap, the system might not be able to fulfill each booking entirely. When you enter a booking into the system, it will assign every seat requested by the booking that hasn't already been assigned to a booking entered into the system earlier. 18 | 19 | What is the largest integer k where there exists an order that you can enter the bookings into the system, such that each booking is assigned at least k seats? 20 | 21 | ## Input 22 | 23 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case starts with a line containing two integers **N** and **Q**, the number of seats and the number of bookings, respectively. Then, there are **Q** more lines, the i-th of which contains the two integers **Li** and **Ri**, indicating that the i-th booking would like to book all the seats from **Li** to **Ri**, inclusive. 24 | 25 | ## Output 26 | 27 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the largest value k, as described above. 28 | 29 | ## Limits 30 | 31 | Time limit: 30 seconds per test set.
32 | Memory limit: 1GB.
33 | **T** = 100.
34 | 1 ≤ N ≤ 106.
35 | 1 ≤ **Li** ≤ **Ri** ≤ N. 36 | 37 | ### Test set 1 (Visible) 38 | 39 | 1 ≤ **Q** ≤ 300. 40 | 41 | ### Test set 2 (Hidden) 42 | 43 | 1 ≤ **Q** ≤ 30000.
44 | For at least 85 of the test cases, **Q** ≤ 3000. 45 | 46 | ## Sample 47 | 48 | | Input | Output | 49 | | ----- | ---------- | 50 | | 3 | | 51 | | 5 3 | Case #1: 1 | 52 | | 1 2 | | 53 | | 3 4 | | 54 | | 2 5 | | 55 | | 30 3 | Case #2: 0 | 56 | | 10 11 | | 57 | | 10 10 | | 58 | | 11 11 | | 59 | | 10 4 | Case #3: 2 | 60 | | 1 8 | | 61 | | 4 5 | | 62 | | 3 6 | | 63 | | 2 7 | | 64 | 65 | In Sample Case #1, there are **N** = 5 seats and **Q** = 3 bookings. One possible order is: 66 | 67 | - Put in the second booking, where the system will book 2 seats (3 and 4). 68 | - Put in the first booking, where the system will book 2 seats (1 and 2). 69 | - Put in the third booking, where the system will book 1 seat (only seat 5, since seats 1, 2, 3 and 4 are already booked). 70 | 71 | Each booking is assigned at least 1 seat, and there is no order that assigns at least 2 seats to each booking, so the answer is 1. 72 | 73 | In Sample Case #2, there are **N** = 30 seats and **Q** = 3 bookings. No matter what order you assign the seats in, at least one booking will have no seats assigned to it. So the answer is 0. Notice that there can be seats that are not part of any bookings! 74 | 75 | In Sample Case #3, there are **N** = 10 seats and **Q** = 4 bookings. One possible order is: 76 | 77 | - Put in the second booking, where the system will book 2 seats (4 and 5). 78 | - Put in the third booking, where the system will book 2 seats (3 and 6, since 4 and 5 are already booked). Notice that the seats booked are not necessarily adjacent to each other. 79 | - Put in the fourth booking, where the system will book 2 seats (2 and 7). 80 | - Put in the first booking, where the system will book 2 seats (1 and 8). 81 | 82 | Each booking is assigned at least 2 seats, and there is no order that assigns at least 3 seats to each booking, so the answer is 2. 83 | 84 | **Note**: We do not recommend using interpreted/slower languages for the Large dataset of this problem. 85 | -------------------------------------------------------------------------------- /Round G/Shifts/solution.js: -------------------------------------------------------------------------------- 1 | process.stdin.resume(); 2 | process.stdin.setEncoding('utf-8'); 3 | 4 | let inputString = ''; 5 | let currentLine = 0; 6 | 7 | process.stdin.on('data', (inputStdin) => { 8 | inputString += inputStdin; 9 | }); 10 | 11 | process.stdin.on('end', (_) => { 12 | inputString = inputString 13 | .trim() 14 | .split('\n') 15 | .map((str) => str.trim()); 16 | solution(); 17 | }); 18 | 19 | function readLine() { 20 | return inputString[currentLine++]; 21 | } 22 | 23 | let segmentTree; 24 | 25 | function solution() { 26 | const T = Number(readLine()); 27 | for (let t = 0; t < T; t++) { 28 | let [N, H] = readLine().split(/\s+/).map(Number); 29 | let happiness = [readLine().split(/\s+/).map(Number), readLine().split(/\s+/).map(Number)]; 30 | let count = 0; 31 | 32 | if (N < 2) { 33 | let combinations = getCombinations(happiness, 0, N); 34 | for (let i = 0; i < combinations.length; i++) { 35 | if (combinations[i][0] >= H && combinations[i][1] >= H) { 36 | count++; 37 | } 38 | } 39 | } else { 40 | let P = Math.ceil(N / 2); 41 | 42 | let A1 = getCombinations(happiness, 0, P); 43 | let A2 = getCombinations(happiness, P, N); 44 | A1.sort((a, b) => (a[0] != b[0] ? a[0] - b[0] : a[1] - b[1])); 45 | A2.sort((a, b) => (a[0] != b[0] ? a[0] - b[0] : a[1] - b[1])); 46 | let p2 = [...new Set(A2.map((a) => a[1]))].sort((a, b) => b - a); 47 | 48 | let keyP2 = {}; 49 | for (let i = 0; i < p2.length; i++) { 50 | keyP2[p2[i]] = i; 51 | } 52 | segmentTree = Array(2 ** (Math.ceil(Math.log2(p2.length)) + 1)).fill(0); 53 | let lastInserted = A2.length; 54 | for (let i = 0; i < A1.length; i++) { 55 | let p1 = A1[i]; 56 | let l1 = Math.max(0, H - p1[0]); 57 | let left = 0; 58 | let right = lastInserted - 1; 59 | let mid; 60 | while (left <= right) { 61 | mid = (left + right) >> 1; 62 | if (A2[mid][0] < l1) { 63 | left = mid + 1; 64 | } else { 65 | right = mid - 1; 66 | } 67 | } 68 | for (let j = left; j < lastInserted; j++) { 69 | update(0, p2.length - 1, keyP2[A2[j][1]]); 70 | } 71 | lastInserted = left; 72 | let l2 = Math.max(0, H - p1[1]); 73 | 74 | left = 0; 75 | right = p2.length - 1; 76 | mid; 77 | while (left <= right) { 78 | mid = (left + right) >> 1; 79 | if (p2[mid] < l2) { 80 | right = mid - 1; 81 | } else { 82 | left = mid + 1; 83 | } 84 | } 85 | count += query(0, p2.length - 1, right); 86 | } 87 | } 88 | console.log(`Case #${t + 1}: ${count}`); 89 | } 90 | } 91 | 92 | function getCombinations(happiness, start, end) { 93 | if (start == end) { 94 | return [0, 0]; 95 | } 96 | 97 | let sum = [0, 0]; 98 | let ans = []; 99 | bt(start); 100 | return ans; 101 | 102 | function bt(id) { 103 | if (id == end) { 104 | ans.push([sum[0], sum[1]]); 105 | return; 106 | } 107 | 108 | sum[0] += happiness[0][id]; 109 | bt(id + 1); 110 | sum[1] += happiness[1][id]; 111 | bt(id + 1); 112 | sum[0] -= happiness[0][id]; 113 | bt(id + 1); 114 | sum[1] -= happiness[1][id]; 115 | } 116 | } 117 | 118 | function update(start, end, at, node = 0) { 119 | segmentTree[node] += 1; 120 | if (at <= start && end <= at) { 121 | return; 122 | } 123 | let mid = (start + end) >> 1; 124 | if (at <= mid) { 125 | let leftChildNode = (node << 1) | 1; 126 | update(start, mid, at, leftChildNode); 127 | } else { 128 | let rightChildNode = (node + 1) << 1; 129 | update(mid + 1, end, at, rightChildNode); 130 | } 131 | } 132 | 133 | function query(start, end, until, node = 0) { 134 | if (until < start || end < 0) { 135 | return 0; 136 | } 137 | if (0 <= start && end <= until) { 138 | return segmentTree[node]; 139 | } 140 | let mid = (start + end) >> 1; 141 | 142 | let leftChildNode = (node << 1) | 1; 143 | let rightChildNode = (node + 1) << 1; 144 | return query(start, mid, until, leftChildNode) + query(mid + 1, end, until, rightChildNode); 145 | } 146 | -------------------------------------------------------------------------------- /Round B/Energy Stones/README.md: -------------------------------------------------------------------------------- 1 | # Energy Stones 2 | 3 | ## Solution code 4 | 5 | See [solution source code](/Round%20B/Energy%20Stones/solution.js) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20B/Energy%20Stones/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Duda the rock monster lives in the enchanted forest and has collected **N** _energy_ stones for lunch. Since he has a small mouth, he eats energy stones one at a time. Some stones are tougher than others! The i-th stone takes him **Si** seconds to eat. 14 | 15 | Duda eats energy stones to get energy. Different stones give him different amounts of energy. Furthermore, the stones lose energy over time. The i-th stone initially contains **Ei** units of energy and will lose **Li** units of energy each second. When Duda starts to eat a stone, he will receive all the energy the stone contains immediately (no matter how much time it takes to actually finish eating the stone). The stone's energy stops decreasing once it hits zero. 16 | 17 | What is the largest amount of energy Duda could receive from eating his stones? 18 | 19 | ## Input 20 | 21 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each test case starts with a line containing the integer **N**, the number of energy stones Duda has. Then, there are **N** more lines, the i-th of which contains the three integers **Si**, **Ei** and **Li**, as described above. 22 | 23 | ## Output 24 | 25 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the maximum amount of energy Duda could receive from eating stones. 26 | 27 | ## Limits 28 | 29 | Time limit: 30 seconds per test set.
30 | Memory limit: 1GB.
31 | 1 ≤ **T** ≤ 100.
32 | 1 ≤ **N** ≤ 100.
33 | 1 ≤ **Si** ≤ 100.
34 | 1 ≤ **Ei** ≤ 105.
35 | 0 ≤ **Li** ≤ 105.
36 | 37 | ### Test set 1 (Visible) 38 | 39 | All stones take the same amount of time to eat. That is: **Si** = **Sj** for all i and j. 40 | 41 | ### Test set 2 (Hidden) 42 | 43 | There are no additional constraints beyond the general Limits. 44 | 45 | | Input | Output | 46 | | --------- | ------------ | 47 | | 3 | | 48 | | 4 | Case #1: 105 | 49 | | 20 10 1 | | 50 | | 5 30 5 | | 51 | | 100 30 1 | | 52 | | 5 80 60 | | 53 | | 3 | Case #2: 8 | 54 | | 10 4 1000 | | 55 | | 10 3 1000 | | 56 | | 10 8 1000 | | 57 | | 2 | Case #3: 500 | 58 | | 12 300 50 | | 59 | | 5 200 0 | | 60 | 61 | In Sample Case #1, there are **N** = 4 stones. One possible order Duda can eat stones is: 62 | 63 | - Eat the fourth stone. This takes 5 seconds and gives him 80 units of energy. 64 | - Eat the second stone. This takes 5 more seconds and gives him 5 units of energy (the second stone started with 30 energy, and over 5 seconds, has lost 25 units of energy). 65 | - Eat the third stone. This takes 100 more seconds and gives him 20 units of energy (the third stone started with 30 energy, and over 10 seconds, has lost 10 units of energy). 66 | - Eat the first stone. This takes 20 more seconds and gives him 0 units of energy (the first stone started with 10 units of energy, and over 110 seconds, has lost all of its energy). 67 | 68 | This gives him 105 units of energy, which is the best he can do. So the answer is 105. 69 | 70 | In Sample Case #2, there are **N** = 3 stones. No matter which stone Duda eats, the other two will have no energy left once he is done eating. So he should eat the third stone, giving him 8 units of energy. 71 | 72 | In Sample Case #3, there are **N** = 2 stones. Duda can: 73 | 74 | - Eat the first stone. This takes 12 seconds and gives him 300 units of energy. 75 | - Eat the second stone. This takes 5 seconds and gives him 200 units of energy (the second stone does not lose any energy over time!). 76 | 77 | So the answer is 500. 78 | 79 | Note that Sample Cases #1 and #3 will not appear in the Visible dataset. Consequently, sample input is not included as a test case for your submissions, and hence any attempts that fail to produce correct output will accrue a penalty. We recommend you to run a manual test in the editor before submitting the attempt. 80 | -------------------------------------------------------------------------------- /Round C/Catch Some/README.md: -------------------------------------------------------------------------------- 1 | # Catch Some 2 | 3 | ## Solution code 4 | 5 | See [solution source code c++](/Round%20C/Catch%20Some/solution.cpp) 6 | 7 | ## Analysis 8 | 9 | You can see [solution analysis](/Round%20C/Catch%20Some/analysis.md) extracted from Google webpage. 10 | 11 | ## Problem 12 | 13 | Bundle is an animal researcher and needs to go observe **K** dogs. She lives on a horizontal street marked at metre increments with consecutive numbers 0, 1, 2, 3 and so on. She begins in her home, which is at position 0. There are also **N** dogs on the street. The i-th dog is **Pi** metres to the right of her home on the street (multiple dogs can share the same position). 14 | 15 | Dogs come in different colors, which are denoted by positive integers. The i-th animal is of color **Ai**. 16 | 17 | If Bundle is at her home, she can change the current color of her shirt. This is important since the dogs are very shy! Bundle can only observe a dog if she is at the same position as that dog, and is wearing a shirt of the same color as the dog. 18 | 19 | It takes Bundle one second to move one metre to the left or right on the street. It takes her no time to change shirts or observe a dog. 20 | 21 | What is the least amount of time it will take Bundle to observe **K** dogs? Note that she _does not_ have to return home after observing **K** dogs. 22 | 23 | ## Input 24 | 25 | The first line of the input gives the number of test cases, **T**. **T** test cases follow. Each testcase begins with a line containing the two integers **N** and **K**, the number of dogs on the number line and the number of dogs Bundle needs to observe, respectively. The second line contains **N** integers, the i-th of which is **Pi**, the position of the i-th dog. The third line contains **N** integers, the i-th of which is **Ai**, the color of the i-th dog. 26 | 27 | ## Output 28 | 29 | For each test case, output one line containing `Case #x: y`, where `x` is the test case number (starting from 1) and `y` is the least time Bundle needs to observe **K** dogs. 30 | 31 | ## Limits 32 | 33 | Time limit: 30 seconds per test set.
34 | Memory limit: 1GB.
35 | 1 ≤ **T** ≤ 100.
36 | 1 ≤ **K** ≤ **N**.
37 | 1 ≤ **Ai** ≤ 1000.
38 | 1 ≤ **Pi** ≤ 105. 39 | 40 | ### Test set 1 (Visible) 41 | 42 | 1 ≤ **N** ≤ 50. 43 | 44 | ### Test set 2 (Hidden) 45 | 46 | 1 ≤ **N** ≤ 1000. 47 | 48 | ## Sample 49 | 50 | | Input | Output | 51 | | --------------- | -------------- | 52 | | 3 | | 53 | | 4 3 | Case #1: 8 | 54 | | 1 2 4 9 | | 55 | | 3 3 2 3 | | 56 | | 4 3 | Case #2: 6 | 57 | | 1 2 3 4 | | 58 | | 1 8 1 8 | | 59 | | 6 6 | Case #3: 10028 | 60 | | 4 3 3 1 3 10000 | | 61 | | 1 2 8 9 5 7 | | 62 | 63 | In Sample Case #1, there are **N** = 4 dogs and Bundle needs to observe **K** = 3 dogs. One way that she can achieve this is as follows: 64 | 65 | - Put on a shirt of color 3. 66 | - Move one metre to the right and observe the dog there. 67 | - Move one metre to the right again and observe the dog there. 68 | - Move two metres to the left, returning to her home. 69 | - Change into a shirt of color 2. 70 | - Move four metres to the right and observe the dog there. 71 | 72 | In total, this takes Bundle 8 seconds which is the least time possible, so the answer is 8. 73 | 74 | In Sample Case #2, there are N = 4 dogs and Bundle needs to observe K = 3 dogs. One way that she can achieve this is as follows: 75 | 76 | - Put on a shirt of color 1. 77 | - Move one metre to the right and observe the dog there. 78 | - Move one metre to the left, returning to her home. 79 | - Change into a shirt of color 8. 80 | - Move two metres to the right and observe the dog there. 81 | - Move two metres to the right again and observe the dog there. Note that Bundle is unable to observe the dog she passes at position 3, since her shirt is the wrong color (even though she was wearing the right colored shirt previously). 82 | 83 | In total, this takes Bundle 6 seconds which is the least time possible, so the answer is 6. 84 | 85 | In Sample Case #3, note that: 86 | 87 | - Multiple dogs can share the same position and 88 | - Dogs are not necessarily given in ascending order of position. 89 | 90 | No explanation is provided for the answer to this case. 91 | --------------------------------------------------------------------------------