updated sorting; added stable_sort, problems, copied comparator for java, wrote coord compression section, fixed merge conflicts

This commit is contained in:
Michael Cao 2020-06-15 20:08:40 -05:00
commit 806171d3e6
15 changed files with 426 additions and 168 deletions

View file

@ -1,5 +1,5 @@
---
id: about-this
id: about
title: About This Guide
author: Nathan Wang, Benjamin Qi
---

View file

@ -0,0 +1,23 @@
---
id: data
title: Data Types
author: Darren Yao
---
There are several main **data types** that are used in contests: 32-bit and 64-bit integers, floating point numbers, booleans, characters, and strings.
<!-- END DESCRIPTION -->
## Reading
- CPH 1.1 - 1.3
The 32-bit integer supports values between $-2\,147\,483\,648$ and $2\,147\,483\,647$, which is roughly equal to $\pm$ $2 \times 10^9$. If the input, output, or \textit{any intermediate values used in calculations} exceed the range of a 32-bit integer, then a 64-bit integer must be used. The range of the 64-bit integer is between $-9\,223\,372\,036\,854\,775\,808$ and $9\,223\,372\,036\,854\,775\,807$ which is roughly equal to $\pm$ $9 \times 10^{18}$. Contest problems are usually set such that the 64-bit integer is sufficient. If it's not, the problem will ask for the answer modulo $m$, instead of the answer itself, where $m$ is a prime. In this case, make sure to use 64-bit integers, and take the remainder of $x$ modulo $m$ after every step using `x %= m;`.
Floating point numbers are used to store decimal values. It is important to know that floating point numbers are not exact, because the binary architecture of computers can only store decimals to a certain precision. Hence, we should always expect that floating point numbers are slightly off. Contest problems will accommodate this by either asking for the greatest integer less than $10^k$ times the value, or will mark as correct any output that is within a certain $\epsilon$ of the judge's answer.
Boolean variables have two possible states: `true` and `false`. We'll usually use booleans to mark whether a certain process is done, and arrays of booleans to mark which components of an algorithm have finished.
Character variables represent a single Unicode character. They are returned when you access the character at a certain index within a string. Characters are represented using the ASCII standard, which assigns each character to a corresponding integer. This allows us to do arithmetic with them; for example, both `cout << ('f' - 'a');` in C++ and `System.out.print('f' - 'a');` in Java will print `5`.
Strings are stored as an array of characters. You can easily access the character at a certain index and take substrings of the string. String problems on USACO are generally very easy and don't involve any special data structures.

View file

@ -0,0 +1,184 @@
---
id: io
title: Input and Output
author: Darren Yao
order: 5
---
Demonstrates how to read in input and print output for USACO.
<!-- END DESCRIPTION -->
## C++
In CodeForces and CSES, input and output are standard, meaning that using the library [<iostream>](http://www.cplusplus.com/reference/iostream/) suffices.
However, in USACO, input is read from a file called `problemname.in`, and printing output to a file called `problemname.out`. Note that you'll have to rename the `.in` and `.out` files. You will need the [<cstdio>](http://www.cplusplus.com/reference/cstdio/) or the [<fstream>](http://www.cplusplus.com/reference/fstream/) library. Essentially, replace every instance of the word *template* in the word below with the input/output file name, which should be given in the problem.
In order to test a program, create a file called `problemname.in`, and then run the program. The output will be printed to `problemname.out`.
Below, we have included C++ templates for input and output. We use `using namespace std;` so that we don't have to preface standard library functions with `std::` each time we use them.
For USACO:
If `<cstdio>` is used:
```cpp
#include <cstdio>
using namespace std;
int main() {
freopen("template.in", "r", stdin);
freopen("template.out", "w", stdout);
}
```
If `<fstream>` is used (note that if you use `<fstream>`, you must replace `cin` and `cout` with `fin` and `fout`):
```cpp
#include <fstream>
using namespace std;
int main() {
ifstream fin("template.in");
ofstream fout("template.out");
}
```
For CodeForces, CSES, and other contests that use standard input and output, simply use the standard input / output from `<iostream>`.
## Java
In your CS classes, you've probably implemented input and output using standard input and standard output, or using `Scanner` to read input and `System.out.print` to print output.
In CodeForces and CSES, input and output are standard, and the above methods work. However, `Scanner` and `System.out.print` are slow when we have to handle inputting and outputting tens of thousands of lines. Thus, we use `BufferedReader` and `PrintWriter` instead, which are faster because they buffer the input and output and handle it all at once as opposed to parsing each line individually.
However, in USACO, input is read from a file called `problemname.in`, and printing output to a file called `problemname.out`. Note that you'll have to rename the `.in` and `.out` files. Essentially, replace every instance of the word *template* in the word below with the input/output file name, which should be given in the problem.
In order to test a program, create a file called `problemname.in`, and then run the program. The output will be printed to `problemname.out`.
Below, we have included Java templates for input and output, which are effectively faster Scanners. We import the entire `util` and `io` libraries for ease of use.
```java
import java.util.*;
import java.io.*;
public class template {
static class InputReader {
BufferedReader reader;
StringTokenizer tokenizer;
public InputReader() throws FileNotFoundException {
reader = new BufferedReader(new FileReader("template.in"));
tokenizer = null;
}
String next() { // reads in the next String
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() { // reads in the next int
return Integer.parseInt(next());
}
public long nextLong() { // reads in the next long
return Long.parseLong(next());
}
public double nextDouble() { // reads in the next double
return Double.parseDouble(next());
}
}
public static void main(String[] args) throws FileNotFoundException, IOException {
InputReader r = new InputReader();
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("template.out")));
// YOUR CODE HERE
pw.close(); // flushes the output once printing is done
}
}
```
For CodeForces, CSES, and other contests that use standard input and output, the template is as follows:
```java
import java.io.*;
import java.util.*;
public class template {
static class InputReader {
BufferedReader reader;
StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
String next() { // reads in the next string
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() { // reads in the next int
return Integer.parseInt(next());
}
public long nextLong() { // reads in the next long
return Long.parseLong(next());
}
public double nextDouble() { // reads in the next double
return Double.parseDouble(next());
}
}
static InputReader r = new InputReader(System.in);
static PrintWriter pw = new PrintWriter(System.out);
public static void main(String[] args) {
// YOUR CODE HERE
pw.close(); // flushes the output once printing is done
}
}
```
Here's a brief description of the methods in our `InputReader` class, with an instance `r`, and `PrintWriter` with an instance `pw`.
(insert table)
Here's an example to show how input/output works. Let's say we want to write a program that takes three numbers as input and prints their sum.
```java
// InputReader template code above
static InputReader r = new InputReader(System.in);
static PrintWriter pw = new PrintWriter(System.out);
public static void main(String[] args) {
int a = r.nextInt();
int b = r.nextInt();
int c = r.nextInt()
pw.println(a + b + c);
pw.close();
}
```

View file

@ -5,54 +5,28 @@ author: Benjamin Qi, William Lin, Eric Wei, Nathan Wang, Nathan Chen, Darren Yao
---
How to practice, when to read editorials (analyses), etc.
<!-- END DESCRIPTION -->
## Practicing
Knowing when to "give up" on a problem and start reading the problem's editorial is challenging. Below are the opinions of various individuals. Note that "give up" is in quotes, because one still learns when they "give up" and read an editorial!
## Reading Editorials
## Darren Yao (Intro to USACO 1.3)
Knowing when to "give up" on a problem and start reading the problem's editorial
is challenging. Below are the opinions of various individuals.
Reaching a high level in competitive programming requires dedication and motivation. For many people, their practice is inefficient because they do problems that are too easy, too hard, or simply of the wrong type.
Note that "give up" is in quotes, because one still learns when they "give up" and read an editorial!
In the lower divisions, most problems use relatively elementary algorithms; the main challenge is deciding which algorithm to use, and implementing it correctly. In a contest, you should spend the bulk of your time thinking about the problem and coming up with the algorithm, rather than typing code. Thus, you should practice your implementation skills, so that during the contest, you can implement the algorithm quickly and correctly, without resorting to debugging.
### Benjamin Qi
If you're still coming up with new ideas, keep thinking. Otherwise, you have several options:
- Look at [part of] the solution. (If CodeForces, look at the tags.)
- Leave it for a while and do something else if you actually want to solve it on your own.
- Get a hint from someone else.
I'm impatient, so usually I go with the first option. Sometimes I end up reading an editorial before reading the statement, but idk if this is a good strategy. :/
In any case, if you thought about a problem a lot during a contest but didn't end up solving it, then I don't see any reason not to read the editorial when it comes out (vs. continuing to think about it on your own). Also, you should always implement the solution afterwards!
### William Lin
> I follow three guidelines (from most important to least important)
> 1. Having fun, just doing whatever you feel like doing
> 2. Spend about the same amount of time that you would be able to during a real contest
> 3. Whether you are making progress or not
### Darren Yao
In general, I think its fine to read the solution relatively early on, as long as youre made several different attempts at it and you can learn effectively from the solution.
- On a bronze problem, read the solution after 15-20 minutes of no meaningful progress, after youve exhausted every idea you can think of.
- On a silver problem, read the solution after 30-40 minutes of no meaningful progress.
- IMPORTANT: When you get stuck and consult the solution, you should not read the entire solution at once, and you certainly shouldnt look at the solution code. Instead, its better to read the solution step by step until you get unstuck, at which point you should go back and finish the problem, and implement it yourself. Reading the full solution or its code should be seen as a last resort.
Problems that you practice with should be of the appropriate difficulty. You don't necessarily need to complete all the exercises at the end of each chapter, just do what you think is right for you. A problem at the right level of difficulty should be one of two types: either you struggle with the problem for a while before coming up with a working solution, or you miss it slightly and need to consult the solution for some small part. If you instantly come up with the solution, a problem is likely too easy, and if you're missing multiple steps, it might be too hard.
- On a bronze problem, read the solution after 15-20 minutes of no meaningful progress, after youve exhausted every idea you can think of.
- On a silver problem, read the solution after 30-40 minutes of no meaningful progress.
- IMPORTANT: When you get stuck and consult the solution, you should not read the entire solution at once, and you certainly shouldnt look at the solution code. Instead, its better to read the solution step by step until you get unstuck, at which point you should go back and finish the problem, and implement it yourself. Reading the full solution or its code should be seen as a last resort.
Problems that you practice with should be of the appropriate difficulty. You don't necessarily need to complete all the exercises at the end of each module, just do what you think is right for you. A problem at the right level of difficulty should be one of two types: either you struggle with the problem for a while before coming up with a working solution, or you miss it slightly and need to consult the solution for some small part. If you instantly come up with the solution, a problem is likely too easy, and if you're missing multiple steps, it might be too hard.
[This](https://web.evanchen.cc/FAQs/raqs.html) and [this](https://usamo.wordpress.com/2019/01/31/math-contest-platitudes-v3/) are two blog posts by Evan Chen that I find quite insightful. They discuss such things as time management, the problem-solving process, and other tips that you may find useful.
### Eric Wei
> read problem editorials some time after thinking "i have no clue what i'm doing please send help" and before "if i stare at this problem for one minute longer i'm going to punch a hole in my computer", figure out the exact time yourself
### Nathan Chen
Read the editorial when you feel like you've stopped making progress; that could be from 1 to 5 hours. However, the most important part about reading the editorial is that you understand the topic and try to think about what similar problems look like. Being generally curious is a good way to practice algorithmic thinking.
### Nathan Wang
## Nathan Wang
My personal opinion is that it is okay to give up early when solving CP problems.
Sometimes I spend as little as 15-20 minutes on a problem before reading the editorial
@ -79,20 +53,45 @@ My justification for why I think it's okay to give up so early is as follows:
Overall, I would just say to "give up" when you feel like giving up, whether that's
in five hours or in 15 minutes :)
### Siyong Huang
## Siyong Huang
There's two ways to grow from solving a problem
There are two ways to grow from solving a problem:
1) You learn a new idea/algorithm from it
### 1 - You learn a new idea/algorithm from it.
You learn ideas from problems you cannot solve. This means that you *need* to read an editorial or someone else's accepted solution. Please try to understand the editorial; it's an important skill to have. You should be re-reading it multiple times and walking through various examples. If this fails, read someone's accepted solution (try to find one that is easy to read, if possible) and figure out what it is doing. If even this doesn't work, ask the author of the solution to explain their logic or specific parts of their code. Trust me, they are extremely happy to help someone who has made an effort to understand the editorial and has used their code as reference.
You learn ideas from problems you cannot solve. This means that you *need* to read an editorial or someone else's accepted solution. Please try to understand the editorial; it's an important skill to have. You should be re-reading it multiple times and walking through various examples. If this fails, read someone's accepted solution (try to find one that is easy to read, if possible) and figure out what it is doing. If even this doesn't work, ask the author of the solution to explain their logic or specific parts of their code. Trust me, many are extremely happy to help someone who has made an effort to understand the editorial and has used their code as reference.
Furthermore, there have been countless cases where people have asked for help before reading the editorial. We will just link the editorial or repeat it for them, which is pointless.
Finally, hints are extremely overrated in my opinion. Just read the whole solution. You don't gain anything from reading part of a solution then finishing it out yourself. As long as you implement it in the end, you are still learning the same thing.
2) Your implementation speed and consistency improves
### 2 - Your implementation speed and consistency improves.
The best way to do this is to solve a bunch of easy or moderate difficulty problems. Try to solve them as fast as possible, as if you were in a contest. Perhaps take virtuals or time yourself when solving problems. Whichever you choose, the more problems you solve, the better you will become.
In terms of implementation speed and consistency, the best way is just to solve a bunch of easy or moderate problems. Try to solve them as fast as possible, as if you were in contest. Perhaps take virtuals or time yourself when solving problems. Whichever you choose, the more problems you solve, the better you will become.
## Benjamin Qi
If you're still coming up with new ideas, keep thinking. Otherwise, you have several options:
- Look at [part of] the solution. (If CodeForces, look at the tags.)
- Leave it for a while and do something else if you actually want to solve it on your own.
- Get a hint from someone else.
I'm impatient, so usually I go with the first option. Sometimes I end up reading an editorial before reading the statement, but idk if this is a good strategy. :/
In any case, if you thought about a problem a lot during a contest but didn't end up solving it, then I don't see any reason not to read the editorial when it comes out (vs. continuing to think about it on your own). Also, you should always implement the solution afterwards!
## Nathan Chen
Read the editorial when you feel like you've stopped making progress; that could be from 1 to 5 hours. However, the most important part about reading the editorial is that you understand the topic and try to think about what similar problems look like. Being generally curious is a good way to practice algorithmic thinking.
## William Lin
> I follow three guidelines (from most important to least important)
> 1. Having fun, just doing whatever you feel like doing
> 2. Spend about the same amount of time that you would be able to during a real contest
> 3. Whether you are making progress or not
## Eric Wei
> read problem editorials some time after thinking "i have no clue what i'm doing please send help" and before "if i stare at this problem for one minute longer i'm going to punch a hole in my computer", figure out the exact time yourself

View file

@ -2,7 +2,6 @@
id: prerequisites
title: Prerequisites
author: Nathan Wang
order: 3
---
Here's what you should learn before reading these resources.

View file

@ -7,14 +7,13 @@ problems:
- bronze_word
- bronze_paint
- bronze_square
order: 5
---
Demonstrates how to read in input and print output for a USACO problem in multiple languages. Also lists some introductory USACO Bronze problems.
Solutions for an introductory USACO problem in multiple languages.
<!-- END DESCRIPTION -->
[Technical Specifications for Contests](http://www.usaco.org/index.php?page=instructions)
[Technical Specifications for USACO Contests](http://www.usaco.org/index.php?page=instructions)
## Example: [Fence Painting](http://usaco.org/index.php?page=viewproblem2&cpid=567)

View file

@ -2,7 +2,6 @@
id: running-cpp
title: Running C++
author: Nathan Wang, Benjamin Qi, Anthony Wang
order: 4
---
Running C++ both online and locally.

View file

@ -2,7 +2,6 @@
id: getting-started
title: Getting Started
author: Nathan Wang, Benjamin Qi, Darren Yao
order: 2
---
- Introduction
@ -18,19 +17,21 @@ Todo:
## Introduction
The goal of competitive programming is to write code to solve given problems quickly. These problems are not open problems; they are problems that are designed to be solved in the short timeframe of a contest, and have already been solved by the problem writer and testers. In general, each problem in competitive programming is solved by a two-step process: coming up with the algorithm, which involves problem solving skills and intuition, and implementing the algorithm, which requires programming skills to translate the algorithm into working code.
The goal of competitive programming is to write code to solve given problems quickly. These problems are not open problems; they are problems that are designed to be solved in the short timeframe of a contest, and have already been solved by the problem writer(s) and tester(s). In general, each problem in competitive programming is solved by a two-step process: coming up with the algorithm, which involves problem solving skills and intuition, and implementing the algorithm, which requires programming skills to translate the algorithm into working code.
A contest generally lasts for several hours, and consists of a set of problems. For each problem, when you complete your code, you submit it to a grader, which checks the answers calculated by the your program against a set of predetermined test cases. For each problem, you are given a time limit and a memory limit that your program must satisfy.
A contest generally lasts for several hours and consists of a set of problems. For each problem, when you complete your code, you submit it to a grader, which checks the answers calculated by the your program against a set of predetermined test cases. For each problem, you are given a time limit and a memory limit that your program must satisfy.
For those of you with experience in software development, note that competitive programming is quite different, as the goal is to write programs that compute the correct answer, run quickly, and can be implemented quickly. Note that nowhere was maintainability of code mentioned. This means that you should throw away everything you know about traditional code writing; you don't need to bother documenting your code, because it only needs to be readable to you, during the contest.
[William Lin - What is Competitive Programming?](https://www.youtube.com/watch?time_continue=1&v=ueNT-w7Oluw)
### Videos
- [William Lin - What is Competitive Programming?](https://www.youtube.com/watch?time_continue=1&v=ueNT-w7Oluw)
- [Kamil Debowski - Interview with a Competitive Programmer](https://www.youtube.com/watch?v=F4rykKLcduI)
- [Example Problem](https://open.kattis.com/contests/mcpc19open/problems/basketballoneonone)
## Contest Format
The USA Computing Olympiad is a national programming competition that occurs four times a year, with December, January, February, and US Open (March) contests. The regular contests are four hours long, and the US Open is five hours long. Each contest contains three problems. Solutions are evaluated and scored against a set of predetermined test cases that are not visible to the student. Scoring is out of 1000 points, with each problem being weighted equally. There are four divisions of contests: Bronze, Silver, Gold, and Platinum. After each contest, students who meet the contest-dependent cutoff for promotion will compete in the next division for future contests.
See [USACO contests](http://www.usaco.org/index.php?page=contests).
The [USA Computing Olympiad](http://www.usaco.org/index.php?page=contests) is a national programming competition that occurs four times a year, with December, January, February, and US Open (March) contests. The regular contests are four hours long, and the US Open is five hours long. Each contest contains three problems. Solutions are evaluated and scored against a set of predetermined test cases that are not visible to the student. Scoring is out of 1000 points, with each problem being weighted equally. There are four divisions of contests: Bronze, Silver, Gold, and Platinum. After each contest, students who meet the contest-dependent cutoff for promotion will compete in the next division for future contests.
## Choosing a Language

View file

@ -1,3 +1,15 @@
---
id: syllabus
title: Syllabus
author: Benjamin Qi, I FORGOT WHO ELSE EVERYONE PUT YOUR NAME HERE :D
---
Below, we've compiled some of the main topics for each division.
<!-- END DESCRIPTION -->
This USACO guide will try to cover all of these topics. Note that USACO contest problems are not limited to just these topics, though _most_ of them should fall into one of the catgories listed below.
# Other Resources
- [USACO -> CPH Topics](https://github.com/bqi343/USACO/blob/master/Contests/USACO%20Links/USACO%20Topics.md)

View file

@ -1,9 +1,25 @@
---
id: rectangle-geometry
title: "Rectangle Geometry"
author: Unknown
author: Darren Yao
---
See 7.1 of https://www.overleaf.com/project/5e73f65cde1d010001224d8a
The extent of "geometry" problems on USACO Bronze are usually quite simple and limited to intersections and unions of squares and rectangles.
usually just loop over 2D array
<!-- END DESCRIPTION -->
- They usually only include two or three squares or rectangles, in which case you can simply draw out cases on paper. This should logically lead to a solution.
- Also, the coordinates typically only go up to $1000$, so a program that performs $\approx 1000^2$ operations (ex. with a nested for loop) should pass.
## Problems
- USACO Bronze
- [Fence Painting](http://usaco.org/index.php?page=viewproblem2&cpid=567)
- 1D geometry!!
- [Square Pasture](http://usaco.org/index.php?page=viewproblem2&cpid=663)
- [Blocked Billboard](http://usaco.org/index.php?page=viewproblem2&cpid=759)
- Rectangles
- [Blocked Billboard II](http://usaco.org/index.php?page=viewproblem2&cpid=783)
- Also rectangles
- Other
- [CF 587 (Div. 3) C: White Sheet](https://codeforces.com/contest/1216/problem/C)

View file

@ -4,34 +4,38 @@ title: "Simulation"
author: Darren Yao
---
Copied and pasted from chapter 5 of Darren's [Intro to USACO]
In many problems, we can simply simulate what we're told to do by the problem statement.
<!-- END DESCRIPTION -->
# Simulation
In many problems, we can simply simulate what we're told to do by the problem statement. Since there's no formal algorithm involved, the intent of the problem is to assess competence with one's programming language of choice and knowledge of built-in data structures. At least in USACO Bronze, when a problem statement says to find the end result of some process, or to find when something occurs, it's usually sufficient to simulate the process.
Since there's no formal algorithm involved, the intent of the problem is to assess competence with one's programming language of choice and knowledge of built-in data structures. At least in USACO Bronze, when a problem statement says to find the end result of some process, or to find when something occurs, it's usually sufficient to simulate the process.
## Example 1
# Example 1
Alice and Bob are standing on a 2D plane. Alice starts at the point (0, 0), and Bob starts at the point (R, S) (1 \leq R, S \leq 1000). Every second, Alice moves M units to the right, and N units up. Every second, Bob moves P units to the left, and Q units down. (1 \leq M, N, P, Q \leq 10). Determine if Alice and Bob will ever meet (be at the same point at the same time), and if so, when.
### Statement
### Input Format
Alice and Bob are standing on a 2D plane. Alice starts at the point $(0, 0)$, and Bob starts at the point $(R, S)$ ($1 \leq R, S \leq 1000$). Every second, Alice moves $M$ units to the right, and $N$ units up. Every second, Bob moves $P$ units to the left, and $Q$ units down. ($1 \leq M, N, P, Q \leq 10$). Determine if Alice and Bob will ever meet (be at the same point at the same time), and if so, when.
The first line of the input contains R and S.
#### Input Format
The second line of the input contains M, N, P, and Q.
The first line of the input contains $R$ and $S$.
### Output Format
The second line of the input contains $M$, $N$, $P$, and $Q$.
Please output a single integer containing the number of seconds after the start at which Alice and Bob meet. If they never meet, please output -1.
#### Output Format
Please output a single integer containing the number of seconds after the start at which Alice and Bob meet. If they never meet, please output $-1$.
### Solution
We can simulate the process. After inputting the values of R, S, M, N, P, and Q, we can keep track of Alice's and Bob's x- and y-coordinates. To start, we initialize variables for their respective positions. Alice's coordinates are initially (0, 0), and Bob's coordinates are (R, S) respectively. Every second, we increase Alice's x-coordinate by M and her y-coordinate by N, and decrease Bob's x-coordinate by P and his y-coordinate by Q.
Now, when do we stop? First, if Alice and Bob ever have the same coordinates, then we are done. Also, since Alice strictly moves up and to the right and Bob strictly moves down and to the left, if Alice's x- or y-coordinates are ever greater than Bob's, then it is impossible for them to meet. Example code will be displayed below (Here, as in other examples, input processing will be omitted):
We can simulate the process. After inputting the values of $R$, $S$, $M$, $N$, $P$, and $Q$, we can keep track of Alice's and Bob's $x$- and $y$-coordinates. To start, we initialize variables for their respective positions. Alice's coordinates are initially \((0, 0)\), and Bob's coordinates are $(R, S)$ respectively. Every second, we increase Alice's $x$-coordinate by $M$ and her $y$-coordinate by $N$, and decrease Bob's $x$-coordinate by $P$ and his $y$-coordinate by $Q$.
```
Now, when do we stop? First, if Alice and Bob ever have the same coordinates, then we are done. Also, since Alice strictly moves up and to the right and Bob strictly moves down and to the left, if Alice's $x$- or $y$-coordinates are ever greater than Bob's, then it is impossible for them to meet.
Example Java code is displayed below. Here, as in other examples, input processing will be omitted).
```java
int ax = 0; int ay = 0; // alice's x and y coordinates
int bx = r; int by = s; // bob's x and y coordinates
int t = 0; // keep track of the current time
@ -49,23 +53,34 @@ if(ax == bx && ay == by){ // if they are in the same location
out.close(); // flush the output
```
For C++, replaces lines such as `out.println(t)` with `cout << t << endl`.
# Example 2
There are N buckets (5 \leq N \leq 10^5), each with a certain capacity C_i (1 \leq C_i \leq 100). One day, after a rainstorm, each bucket is filled with A_i units of water (1\leq A_i \leq C_i). Charlie then performs the following process: he pours bucket 1 into bucket 2, then bucket 2 into bucket 3, and so on, up until pouring bucket N-1 into bucket N. When Charlie pours bucket B into bucket B+1, he pours as much as possible until bucket B is empty or bucket B+1 is full. Find out how much water is in each bucket once Charlie is done pouring.
### Input Format
The first line of the input contains N.
## Example 2
The second line of the input contains the capacities of the buckets, C_1, C_2, \dots, C_n.
### Statement
The third line of the input contains the amount of water in each bucket A_1, A_2, \dots, A_n.
There are $N$ buckets ($5 \leq N \leq 10^5$), each with a certain capacity $C_i$ ($1 \leq C_i \leq 100$). One day, after a rainstorm, each bucket is filled with $A_i$ units of water ($1\leq A_i \leq C_i$). Charlie then performs the following process: he pours bucket 1 into bucket 2, then bucket 2 into bucket 3, and so on, up until pouring bucket $N-1$ into bucket $N$. When Charlie pours bucket $B$ into bucket $B+1$, he pours as much as possible until bucket $B$ is empty or bucket $B+1$ is full. Find out how much water is in each bucket once Charlie is done pouring.
### Output Format
Please print one line of output, containing N space-separated integers: the final amount of water in each bucket once Charlie is done pouring.
#### Input Format
The first line of the input contains $N$.
The second line of the input contains the capacities of the buckets, $C_1, C_2, \dots, C_N$.
The third line of the input contains the amount of water in each bucket $A_1, A_2, \dots, A_N$.
#### Output Format
Please print one line of output, containing $N$ space-separated integers: the final amount of water in each bucket once Charlie is done pouring.
### Solution
Once again, we can simulate the process of pouring one bucket into the next. The amount of milk poured from bucket B to bucket B+1 is the smaller of the amount of water in bucket B (after all previous operations have been completed) and the remaining space in bucket B+1, which is C_{B+1} - A_{B+1}. We can just handle all of these operations in order, using an array C to store the maximum capacities of each bucket, and an array A to store the current water level in each bucket, which we update during the process. Example code is below (note that arrays are zero-indexed, so the indices of our buckets go from 0 to N-1 rather than from 1 to N).
```
Once again, we can simulate the process of pouring one bucket into the next. The amount of milk poured from bucket $B$ to bucket $B+1$ is the smaller of the amount of water in bucket $B$ (after all previous operations have been completed) and the remaining space in bucket $B+1$, which is $C_{B+1} - A_{B+1}$. We can just handle all of these operations in order, using an array C to store the maximum capacities of each bucket, and an array A to store the current water level in each bucket, which we update during the process. Example code is below (note that arrays are zero-indexed, so the indices of our buckets go from $0$ to $N-1$ rather than from $1$ to $N$).
Java:
```java
for(int i = 0; i < n-1; i++){
int amt = Math.min(A[i], C[i+1]-A[i+1]);
// the amount of water to be poured is the lesser of
@ -83,35 +98,32 @@ pw.println(); // print newline
pw.close(); // flush the output
```
C++:
```cpp
for(int i = 0; i < n-1; i++){
int amt = min(A[i], C[i+1]-A[i+1]);
// the amount of water to be poured is the lesser of
// the amount of water in the current bucket and
// the amount of additional water that the next bucket can hold
A[i] -= amt; // remove the amount from the current bucket
A[i+1] += amt; // add it to the next bucket
}
for(int i = 0; i < n; i++){
cout << A[i] << " ";
// print the amount of water in each bucket at the end
}
cout << endl;
```
## USACO Bronze Problems
# Problems
- [Mixing Milk](http://www.usaco.org/index.php?page=viewproblem2&cpid=855)
- [Milk Measurement](http://www.usaco.org/index.php?page=viewproblem2&cpid=761)
- [The Lost Cow](http://www.usaco.org/index.php?page=viewproblem2&cpid=735)
- [Why Did the Cow Cross the Road III](http://www.usaco.org/index.php?page=viewproblem2&cpid=713)
- [Mowing the Field](http://www.usaco.org/index.php?page=viewproblem2&cpid=593)
- [The Bovine Shuffle](http://usaco.org/index.php?page=viewproblem2&cpid=760)
- [Circular Barn](http://usaco.org/index.php?page=viewproblem2&cpid=616)
- [Circular Barn](http://usaco.org/index.php?page=viewproblem2&cpid=616)

View file

@ -4,34 +4,35 @@ title: "Complete Search"
author: Darren Yao
---
Copied and pasted from CH 6 of Darren's Intro to USACO
In many problems (especially in Bronze), it's sufficient to check all possible cases in the solution space, whether it be all elements, all pairs of elements, or all subsets, or all permutations. Unsurprisingly, this is called **complete search** (or **brute force**), because it completely searches the entire solution space.
<!-- END DESCRIPTION -->
# Complete Search / Brute Force
In many problems (especially in Bronze), it's sufficient to check all possible cases in the solution space, whether it be all elements, all pairs of elements, or all subsets, or all permutations. Unsurprisingly, this is called complete search (or brute force), because it completely searches the entire solution space.
## Example 1
### Statement
# Example 1
You are given N (3 \leq N \leq 5000) integer points on the coordinate plane. Find the square of the maximum Euclidean distance (aka length of the straight line) between any two of the points.
You are given $N$ $(3 \leq N \leq 5000)$ integer points on the coordinate plane. Find the square of the maximum Euclidean distance (aka length of the straight line) between any two of the points.
### Input Format
#### Input Format
The first line contains an integer N.
The first line contains an integer $N$.
The second line contains N integers, the x-coordinates of the points: x_1, x_2, \dots, x_n (-1000 \leq x_i \leq 1000).
The second line contains $N$ integers, the $x$-coordinates of the points: $x_1, x_2, \dots, x_N$ ($-1000 \leq x_i \leq 1000$).
The third line contains N integers, the y-coordinates of the points: y_1, y_2, \dots, y_n (-1000 \leq y_i \leq 1000).
The third line contains $N$ integers, the $y$-coordinates of the points: $y_1, y_2, \dots, y_N$ ($-1000 \leq y_i \leq 1000$).
### Output Format
#### Output Format
Print one integer, the square of the maximum Euclidean distance between any two of the points.
### Solution
We can brute-force every pair of points and find the square of the distance between them, by squaring the formula for Euclidean distance: distance^2 = (x_2-x_1)^2 + (y_2-y_1)^2. Thus, we store the coordinates in arrays `X[]` and `Y[]` such that `X[]` and `Y[]` are the x- and y-coordinates of the i_{th} point, respectively. Then, we iterate through all possible pairs of points, using a variable max to store the maximum square of distance between any pair seen so far, and if the square of the distance between a pair is greater than our current maximum, we set our current maximum to it.
We can brute-force every pair of points and find the square of the distance between them, by squaring the formula for Euclidean distance: $\text{distance}^2 = (x_2-x_1)^2 + (y_2-y_1)^2$. Thus, we store the coordinates in arrays \mintinline{java}{X[]} and \mintinline{java}{Y[]}, such that \mintinline{java}{X[i]} and \mintinline{java}{Y[i]} are the $x$- and $y$-coordinates of the $i_{th}$ point, respectively. Then, we iterate through all possible pairs of points, using a variable max to store the maximum square of distance between any pair seen so far, and if the square of the distance between a pair is greater than our current maximum, we set our current maximum to it.
```
Java:
```java
int max = 0; // storing the current maximum
for(int i = 0; i < n; i++){ // for each first point
for(int j = i+1; j < n; j++){ // for each second point
@ -45,27 +46,39 @@ for(int i = 0; i < n; i++){ // for each first point
pw.println(max);
```
A couple notes: first, since we're iterating through all pairs of points, we start the j loop from j = i+1 so that point i and point j are never the same point. Furthermore, it makes it so that each pair is only counted once. In this problem, it doesn't matter whether we double-count pairs or whether we allow i and j to be the same point, but in other problems where we're counting something rather than looking at the maximum, it's important to be careful that we don't overcount. Secondly, the problem asks for the square of the maximum Euclidean distance between any two points. Some students may be tempted to maintain the maximum distance in a variable, and then square it at the end when outputting. However, the problem here is that while the square of the distance between two integer points is always an integer, the distance itself isn't guaranteed to be an integer. Thus, we'll end up shoving a non-integer value into an integer variable, which truncates the decimal part. Using a floating point variable isn't likely to work either, due to precision errors (use of floating point decimals should generally be avoided when possible).
C++
```cpp
int high = 0; // storing the current maximum
for(int i = 0; i < n; i++){ // for each first point
for(int j = i+1; j < n; j++){ // for each second point
int dx = x[i] - x[j];
int dy = y[i] - y[j];
high = max(high, dx*dx + dy*dy);
// if the square of the distance between the two points is greater than
// our current maximum, then update the maximum
}
}
cout << high << endl;
```
# Generating Permutations
A permutation is a reordering of a list of elements. Some problems will ask for an ordering of elements that satisfies certain conditions. In these problems, if N \leq 10, we can probably iterate through all permutations and check each permutation for validity. For a list of N elements, there are N! ways to permute them, and generally we'll need to read through each permutation once to check its validity, for a time complexity of O(N * N!).
A couple notes: first, since we're iterating through all pairs of points, we start the $j$ loop from $j = i+1$ so that point $i$ and point $j$ are never the same point. Furthermore, it makes it so that each pair is only counted once. In this problem, it doesn't matter whether we double-count pairs or whether we allow $i$ and $j$ to be the same point, but in other problems where we're counting something rather than looking at the maximum, it's important to be careful that we don't overcount. Secondly, the problem asks for the square of the maximum Euclidean distance between any two points. Some students may be tempted to maintain the maximum distance in a variable, and then square it at the end when outputting. However, the problem here is that while the square of the distance between two integer points is always an integer, the distance itself isn't guaranteed to be an integer. Thus, we'll end up shoving a non-integer value into an integer variable, which truncates the decimal part. Using a floating point variable isn't likely to work either, due to precision errors (use of floating point decimals should generally be avoided when possible).
In Java, we'll have to implement this ourselves, which is called Heap's Algorithm (no relation to the heap data structure). What's going to be in the check function depends on the problem, but it should verify whether the current permutation satisfies the constraints given in the problem.
(uh, have you verified this claim?)
## Generating Permutations
A **permutation** is a reordering of a list of elements. Some problems will ask for an ordering of elements that satisfies certain conditions. In these problems, if $N \leq 10$, we can probably iterate through all permutations and check each permutation for validity. For a list of $N$ elements, there are $N!$ ways to permute them, and generally we'll need to read through each permutation once to check its validity, for a time complexity of $O(N \cdot N!)$.
In Java, we'll have to implement this ourselves, which is called [Heap's Algorithm](https://en.wikipedia.org/wiki/Heap%27s_algorithm) (no relation to the heap data structure). What's going to be in the check function depends on the problem, but it should verify whether the current permutation satisfies the constraints given in the problem.
As an example, here are the permutations generated by Heap's Algorithm for \([1, 2, 3]\):
- [1, 2, 3],
- [2, 1, 3],
- [3, 1, 2],
- [1, 3, 2],
- [2, 3, 1],
- [3, 2, 1]
$$[1, 2, 3], [2, 1, 3], [3, 1, 2], [1, 3, 2], [2, 3, 1], [3, 2, 1]$$
Code for iterating over all permutations is as follows:
```
```java
// this method is called with k equal to the length of arr
static void generate(int[] arr, int k){
if(k == 1){
@ -84,35 +97,35 @@ static void generate(int[] arr, int k){
}
}
```
In C++, we can just use the `next_permutation()` function. To iterate through all permutations, place this inside a do-while loop.
```cpp
do {
check(v); // process or check the current permutation for validity
} while(next_permutation(v.begin(), v.end()));
```
# Problems
- [Triangles](http://usaco.org/index.php?page=viewproblem2&cpid=1011)
## Problems
- USACO Bronze
- [Triangles](http://usaco.org/index.php?page=viewproblem2&cpid=1011)
- [Photoshoot](http://www.usaco.org/index.php?page=viewproblem2&cpid=988)
- Hint: Figure out what exactly you're complete searching
- [Cow Gymnastics](http://usaco.org/index.php?page=viewproblem2&cpid=963)
- Hint: Brute force over all possible pairs
- [Milk Pails](http://usaco.org/index.php?page=viewproblem2&cpid=615)
- [Lifeguards](http://usaco.org/index.php?page=viewproblem2&cpid=784)
- Hint: Try removing each lifeguard one at a time.
- [Where Am I?](http://usaco.org/index.php?page=viewproblem2&cpid=964)
- Hint: Brute force over all possible substrings.
- (Permutations) [Livestock Lineup](http://usaco.org/index.php?page=viewproblem2&cpid=965)
- [Field Reduction](http://www.usaco.org/index.php?page=viewproblem2&cpid=641)
- Hint: For this problem, you can't do a full complete search; you have to do a reduced search)
- [Back and Forth](http://www.usaco.org/index.php?page=viewproblem2&cpid=857)
- Somewhat harder
- CSES
- (Permutations) [Chessboard and Queens](https://cses.fi/problemset/task/1624)
- [Photoshoot](http://www.usaco.org/index.php?page=viewproblem2&cpid=988)
(Hint: Figure out what exactly you're complete searching)
- [Cow Gymnastics](http://usaco.org/index.php?page=viewproblem2&cpid=963)
(Hint: Brute force over all possible pairs)
- [Milk Pails](http://usaco.org/index.php?page=viewproblem2&cpid=615)
- [Lifeguards](http://usaco.org/index.php?page=viewproblem2&cpid=784)
(Hint: Try removing each lifeguard one at a time).
- [ Where Am I?](http://usaco.org/index.php?page=viewproblem2&cpid=964)
(Hint: Brute force over all possible substrings)
- (Permutations) [Livestock Lineup](http://usaco.org/index.php?page=viewproblem2&cpid=965)
- (Permutations) [Chessboard and Queens](https://cses.fi/problemset/task/1624)
- [Field Reduction](http://www.usaco.org/index.php?page=viewproblem2&cpid=641)
(Hint: For this problem, you can't do a full complete search; you have to do a reduced search)
- [Back and Forth](http://www.usaco.org/index.php?page=viewproblem2&cpid=857)
(Somewhat harder)

View file

@ -10,9 +10,9 @@ In programming contests, there is a strict limit on program runtime. This means
For USACO, this limit is $4$ seconds for Java submissions. A conservative estimate for the number of operations the grading server can handle per second is $10^8$ (but could be closer to $5 \cdot 10^8$ given good constant factors).
## [Big O Notation](https://en.wikipedia.org/wiki/Big_O_notation) and Complexity Calculations
## Complexity Calculations
We want a method of how many operations it takes to run each algorithm, in terms of the input size $n$. Fortunately, this can be done relatively easily using **Big O notation**, which expresses worst-case complexity as a function of $n$ as $n$ gets arbitrarily large. Complexity is an upper bound for the number of steps an algorithm requires as a function of the input size. In Big O notation, we denote the complexity of a function as $O(f(n))$, where $f(n)$ is a function without constant factors or lower-order terms. We'll see some examples of how this works, as follows.
We want a method of how many operations it takes to run each algorithm, in terms of the input size $n$. Fortunately, this can be done relatively easily using [Big O Notation](https://en.wikipedia.org/wiki/Big_O_notation), which expresses worst-case complexity as a function of $n$ as $n$ gets arbitrarily large. Complexity is an upper bound for the number of steps an algorithm requires as a function of the input size. In Big O notation, we denote the complexity of a function as $O(f(n))$, where $f(n)$ is a function without constant factors or lower-order terms. We'll see some examples of how this works, as follows.
The following code is $O(1)$, because it executes a constant number of operations.

View file

@ -27,19 +27,19 @@ TODO List:
- Coordinate Compression
-->
# Sorting
**Sorting** is exactly what it sounds like: arranging items in some particular order.
Sorting is exactly what it sounds like: arranging items in some particular order.
<!-- END DESCRIPTION -->
## Sorting Algorithms
There are many sorting algorithms, here are some sources to learn about the popular ones:
- [Bubble Sort](https://www.hackerrank.com/challenges/ctci-bubble-sort/problem)
- [Out of Sorts (Silver)](http://www.usaco.org/index.php?page=viewproblem2&cpid=834)
- [Quicksort](https://www.hackerearth.com/practice/algorithms/sorting/quick-sort/tutorial/)
- [Mergesort](https://www.hackerearth.com/practice/algorithms/sorting/merge-sort/tutorial/)
## Library Sorting
- C++:
- [std::sort Documentation](https://en.cppreference.com/w/cpp/algorithm/sort)
- [C++ Tricks (First Two Related To Sorting)](https://codeforces.com/blog/entry/74684)
@ -57,14 +57,13 @@ Problems:
## Custom Comparators
*Custom comparators* allow the user to define how the elements are ordered.
*Custom comparators* define how the elements are ordered.
- [Wormhole Sort (Silver)](http://www.usaco.org/index.php?page=viewproblem2&cpid=992)
This section is very language-specific and will be separated for cpp, java, and python.
This section is very language-specific and will be separated by language.
### C++
This section explains how to implement custom comparators in c++
Side note: In C++, a comparator must return false for two identical objects (not doing so results in undefined behavior and potentially RTE)
#### Comparators for Sorting
@ -372,3 +371,4 @@ By compressing queries and haybale positions, we've transformed the range of poi
- [Breaking Java Arrays.sort()](https://codeforces.com/blog/entry/4827)
- no longer works, see [this one](https://codeforces.com/contest/1324/hacks/625031/test) instead.
- to avoid getting hacked, [shuffle](https://pastebin.com/k6gCRJDv) the array beforehand.

View file

@ -4,7 +4,8 @@ const ModuleOrdering = {
"getting-started",
"prerequisites",
"running-cpp",
"problems"
"problems",
"syllabus",
],
"general": [
"resources",